/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.js.support; import javax.annotation.Nullable; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextAction; import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.Script; import org.mozilla.javascript.Scriptable; import org.obiba.magma.Variable; import org.obiba.magma.js.MagmaContext; import org.obiba.magma.js.ScriptableValue; import org.obiba.magma.js.ScriptableVariable; import org.obiba.magma.support.DatasourceCopier.VariableTransformer; import org.obiba.magma.type.TextType; /** * */ public class JavascriptVariableTransformer implements VariableTransformer { private static final String SCRIPT_NAME = "customScript"; private final String script; private Script compiledScript; public JavascriptVariableTransformer(String script) { this.script = script; initialise(); } @Override public Variable transform(final Variable variable) { String newName = (String) ContextFactory.getGlobal().call(new ContextAction() { @Nullable @Override public Object run(Context ctx) { MagmaContext context = MagmaContext.asMagmaContext(ctx); // Don't pollute the global scope Scriptable scope = new ScriptableVariable(context.newLocalScope(), variable); Object value = compiledScript.exec(ctx, scope); if(value instanceof String) { return value; } if(value instanceof ScriptableValue) { ScriptableValue scriptable = (ScriptableValue) value; if(scriptable.getValueType().equals(TextType.get())) { return scriptable.getValue().isNull() ? null : scriptable.getValue().getValue(); } } return null; } }); return Variable.Builder.sameAs(variable).name(newName != null ? newName : variable.getName()).build(); } public void initialise() { if(script == null) { throw new NullPointerException("script cannot be null"); } compiledScript = (Script) ContextFactory.getGlobal().call(new ContextAction() { @Override public Object run(Context cx) { return cx.compileString(getScript(), getScriptName(), 1, null); } }); } public String getScriptName() { return SCRIPT_NAME; } public String getScript() { return script; } }