public TemplateScript()

in src/main/java/org/apache/commons/jexl3/internal/TemplateScript.java [115:194]


    public TemplateScript(final TemplateEngine engine,
                          final JexlInfo jexlInfo,
                          final String directive,
                          final Reader reader,
                          final String... parms) {
        Objects.requireNonNull(directive, "directive");
        final String engineImmediateCharString = Character.toString(engine.getImmediateChar());
        final String engineDeferredCharString = Character.toString(engine.getDeferredChar());

        if (engineImmediateCharString.equals(directive)
                || engineDeferredCharString.equals(directive)
                || (engineImmediateCharString + "{").equals(directive)
                || (engineDeferredCharString + "{").equals(directive)) {
            throw new IllegalArgumentException(directive + ": is not a valid directive pattern");
        }
        Objects.requireNonNull(reader, "reader");
        this.jxlt = engine;
        this.prefix = directive;
        final List<Block> blocks = jxlt.readTemplate(prefix, reader);
        final List<TemplateExpression> uexprs = new ArrayList<>();
        final StringBuilder strb = new StringBuilder();
        int nuexpr = 0;
        int codeStart = -1;
        int line = 1;
        for (int b = 0; b < blocks.size(); ++b) {
            final Block block = blocks.get(b);
            final int bl = block.getLine();
            while(line < bl) {
                strb.append("//\n");
                line += 1;
            }
            if (block.getType() == BlockType.VERBATIM) {
                strb.append("jexl:print(");
                strb.append(nuexpr++);
                strb.append(");\n");
                line += 1;
            } else {
                // keep track of first block of code, the frame creator
                if (codeStart < 0) {
                    codeStart = b;
                }
                final String body = block.getBody();
                strb.append(body);
                for(int c = 0; c < body.length(); ++c) {
                    if (body.charAt(c) == '\n') {
                        line += 1;
                    }
                }
            }
        }
        // create the script
        final JexlInfo info = jexlInfo == null ? jxlt.getEngine().createInfo() : jexlInfo;
        // allow lambda defining params
        final Scope scope = parms == null ? null : new Scope(null, parms);
        script = jxlt.getEngine().parse(info.at(1, 1), false, strb.toString(), scope).script();
        // seek the map of expression number to scope so we can parse Unified
        // expression blocks with the appropriate symbols
        final Map<Integer, JexlNode.Info> minfo = new TreeMap<>();
        collectPrintScope(script.script(), minfo);
        // jexl:print(...) expression counter
        int jpe = 0;
        // create the exprs using the intended scopes
        for (final Block block : blocks) {
            if (block.getType() == BlockType.VERBATIM) {
                final JexlNode.Info ji = minfo.get(jpe);
                TemplateExpression te;
                // no node info means this verbatim is surrounded by comments markers;
                // expr at this index is never called
                if (ji != null) {
                    te = jxlt.parseExpression(ji, block.getBody(), scopeOf(ji));
                } else {
                    te = jxlt.new ConstantExpression(block.getBody(), null);
                }
                uexprs.add(te);
                jpe += 1;
            }
        }
        source = blocks.toArray(new Block[0]);
        exprs = uexprs.toArray(new TemplateExpression[0]);
    }