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

com.bluenimble.platform.templating.impls.DefaultExpressionCompiler Maven / Gradle / Ivy

There is a newer version: 2.50.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.bluenimble.platform.templating.impls;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.bluenimble.platform.Lang;
import com.bluenimble.platform.templating.Expression;
import com.bluenimble.platform.templating.ExpressionCompiler;
import com.bluenimble.platform.templating.ScriptNode;
import com.bluenimble.platform.templating.TextNode;
import com.bluenimble.platform.templating.VariableNode;

public class DefaultExpressionCompiler implements ExpressionCompiler {
	
	private static final long serialVersionUID = 4204895240965684512L;
	
	protected int 		cacheSize 		= 50;
	
	protected String 	expStart 		= "[";
	protected String 	expEnd 			= "]";
	
	private ScriptEngine scriptEngine;
	
	protected Map cached; 
	
	public DefaultExpressionCompiler () {
		this (false);
	}
	
	public DefaultExpressionCompiler (boolean withScripting) {
		withScripting (withScripting);
	}
	
	public DefaultExpressionCompiler (int cacheSize, String expStart, String expEnd) {
		this (expStart, expEnd);
		this.cacheSize 	= cacheSize;
	}
	
	public DefaultExpressionCompiler (String expStart, String expEnd) {
		this.expStart 	= expStart;
		this.expEnd		= expEnd;
	}
	
	@Override
	public Expression compile (String text, String id) {
		if (Lang.isNullOrEmpty (text)) {
			return null;
		}
		
		String key = id == null ? text : id;
		if (cached != null && cached.containsKey (key)) {
			return cached.get (key);
		}
		
		// compile
		Expression expression = compile (text);
		
		// cache
		if (cacheSize > 0 && expression != null) {
			if (cached == null) {
				cached = new ConcurrentHashMap ();
			}

			if (cached.size () < cacheSize) {
				cached.put (key, expression);
			}
		}
		
		return expression;
	}
	
	private Expression compile (String text) {
		
		Expression expression = new DefaultExpression ();
		
		text = expression.prepare (text);
		
		int indexOfStart = text.indexOf (expStart);
		if (indexOfStart < 0) {
			expression.node (new TextNode (text));
			return expression;
		} 

		// create a text node for the starting part of the text 
		expression.node (new TextNode (text.substring (0, indexOfStart)));
		text = text.substring (indexOfStart + expStart.length ());
		
		while (indexOfStart > -1) {
			int indexOfEnd = text.indexOf (expEnd);
			if (indexOfEnd <= -1) {
				expression.node (new TextNode (expStart + text));
				return expression;
			}
			
			// add a var node
			String var = text.substring (0, indexOfEnd);
			
			// it's a script
			if (var.startsWith (Lang.EQUALS)) {
				if (scriptEngine != null) {
					try {
						expression.node (new ScriptNode (scriptEngine, var.substring (1)));
					} catch (ScriptException e) {
						throw new RuntimeException (e.getMessage (), e);
					}
				} else {
					expression.node (new VariableNode (var.substring (1)));
				}
			} else {
				expression.node (new VariableNode (var));
			}
			
			text = text.substring (indexOfEnd + expEnd.length ());

			indexOfStart = text.indexOf (expStart);
			
			// add text before var
			if (indexOfStart < 0) {
				expression.node (new TextNode (text));
				break;
			} else {
				expression.node (new TextNode (text.substring (0, indexOfStart)));
				text = text.substring (indexOfStart + expStart.length ());
			}
			
		}
		
		return expression;
	}
	
	public DefaultExpressionCompiler cacheSize (int cacheSize) {
		this.cacheSize = cacheSize;
		return this;
	}
	
	public DefaultExpressionCompiler withScripting (boolean withScripting) {
		if (withScripting && scriptEngine == null) {
			scriptEngine = new ScriptEngineManager ().getEngineByName ("js");
		}
		return this;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy