package mireka.startup; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.Stack; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.script.ScriptEngine; import javax.script.ScriptException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * ScriptApi provides functions which are called from the configuration scripts. */ public class ScriptApi { private final Logger logger = LoggerFactory.getLogger(ScriptApi.class); public ScriptEngine engine; public final Stack<File> includeStack = new Stack<>(); /** * Include another configuration file. * * @return the result of the included file, in case of JavaScript, this is * the result of the last statement. * @param fileName * the path to the script file to be included. Relative paths are * resolved against the mireka.home directory. * @throws IOException * thrown if the file cannot be opened * @throws ScriptException * thrown if the script in the included file cannot be run * because of a syntactic or semantic error */ public Object include(String fileName) throws IOException, ScriptException { File file = new File(fileName); String oldSourceFileName = (String) engine.get(ScriptEngine.FILENAME); engine.put(ScriptEngine.FILENAME, file.toString()); includeStack.push(file); try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) { logger.debug("Evaluating " + file.toString() + "..."); Object result = engine.eval(reader); logger.debug("Completed " + file.toString()); includeStack.pop(); engine.put(ScriptEngine.FILENAME, oldSourceFileName); return result; } } /** * Registers objects created by the configuration script for lifecycle * management, which includes calling methods marked with * {@link PostConstruct} and {@link PreDestroy} annotations. * * @param object * the object which may have a lifecycle annotation. * @return the object argument * * @see Lifecycle */ public Object manage(Object object) { Lifecycle.addManagedObject(object); return object; } /** * Registers the object as an object which can be injected later into an * uninitialized property. * * @param object * The object which can be injected * @return the object argument * @see DependencyInjection#addInjectable(Object) */ public Object addInjectableObject(Object object) { DependencyInjection.addInjectable(object); return object; } /** * Initializes the properties that has not got a value explicitly and are * annotated with @Inject annotation with default objects selected from the * set of injectable objects. * * @param object * The object that may have uninitialized properties * @param initializedProperties * The list of properties which were explicitly initialized. * @see DependencyInjection#injectDependencies(Object, List) */ public void injectMissingPropertyValues(Object object, List<String> initializedProperties) { DependencyInjection.injectDependencies(object, initializedProperties); } }