All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ovea.markup.mvel.CompiledImportNode Maven / Gradle / Ivy

/**
 * Copyright (C) 2011 Ovea 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ovea.markup.mvel;

import com.ovea.markup.Execution;
import com.ovea.markup.TemplateMergingCallback;
import org.mvel2.MVEL;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.templates.CompiledTemplate;
import org.mvel2.templates.TemplateCompiler;
import org.mvel2.templates.TemplateRuntime;
import org.mvel2.templates.res.CompiledIncludeNode;
import org.mvel2.templates.res.Node;
import org.mvel2.templates.util.TemplateOutputStream;
import org.mvel2.util.ExecutionStack;

import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Field;

import static org.mvel2.templates.util.TemplateTools.captureToEOS;
import static org.mvel2.util.ParseTools.subset;

public class CompiledImportNode extends Node {
    private static final ThreadLocal relativePathStack;
    private static final ThreadLocal currentCallBack = new ThreadLocal();

    private char[] includeExpression;
    private char[] preExpression;

    private Serializable cIncludeExpression;
    private Serializable cPreExpression;
    private long fileDateStamp;
    private CompiledTemplate cFileCache;

    static {
        try {
            Field relativePathStackField = CompiledIncludeNode.class.getDeclaredField("relativePathStack");
            relativePathStackField.setAccessible(true);
            relativePathStack = (ThreadLocal) relativePathStackField.get(null);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public void setContents(char[] contents) {
        super.setContents(contents);
        int mark;
        cIncludeExpression = MVEL.compileExpression(this.includeExpression = subset(contents, 0, mark = captureToEOS(contents, 0)));
        if (mark != contents.length)
            cPreExpression = MVEL.compileExpression(this.preExpression = subset(contents, ++mark, contents.length - mark));
    }

    @Override
    public Object eval(final TemplateRuntime runtime, final TemplateOutputStream appender, final Object ctx, final VariableResolverFactory factory) {
        final String file = MVEL.executeExpression(cIncludeExpression, ctx, factory, String.class);
        TemplateMergingCallback cb = CompiledImportNode.currentCallBack.get();
        Execution execution = new Execution() {
            @Override
            public TemplateOutputStream proceed() {
                if (cPreExpression != null) {
                    MVEL.executeExpression(cPreExpression, ctx, factory);
                }
                if (next != null) {
                    return appender.append(String.valueOf(TemplateRuntime.eval(readFile(file, ctx, factory), ctx, factory)));
                } else {
                    return appender.append(String.valueOf(MVEL.eval(readFile(file, ctx, factory), ctx, factory)));
                }
            }
        };
        TemplateOutputStream templateOutputStream = cb == null ? execution.proceed() : cb.onImport(CompiledIncludeNode.getFile(file), ctx, execution);
        if (next != null) {
            return next.eval(runtime, templateOutputStream, ctx, factory);
        } else {
            return templateOutputStream;
        }
    }

    @Override
    public boolean demarcate(Node terminatingNode, char[] template) {
        return false;
    }

    private String readFile(String fileName, Object ctx, VariableResolverFactory factory) {
        File file = CompiledIncludeNode.getFile(fileName);
        if (fileDateStamp == 0 || fileDateStamp != file.lastModified()) {
            fileDateStamp = file.lastModified();
            cFileCache = TemplateCompiler.compileTemplate(CompiledIncludeNode.readInFile(file));
        }
        return String.valueOf(TemplateRuntime.execute(cFileCache, ctx, factory));
    }

    static void setCurrentCallBack(TemplateMergingCallback currentCallBack) {
        CompiledImportNode.currentCallBack.set(currentCallBack);
    }

    static void clearCurrentCallBack() {
        CompiledImportNode.currentCallBack.remove();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy