/* * 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.Value; import org.obiba.magma.Variable; import org.obiba.magma.VariableEntity; import org.obiba.magma.js.MagmaContext; import org.obiba.magma.js.ScriptableValue; import org.obiba.magma.js.ScriptableVariable; import org.obiba.magma.support.DatasourceCopier; import org.obiba.magma.type.TextType; public class JavascriptMultiplexingStrategy implements DatasourceCopier.MultiplexingStrategy { private static final String SCRIPT_NAME = "customScript"; private final String script; private Script compiledScript; public JavascriptMultiplexingStrategy(String script) { this.script = script; initialise(); } 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 getScript() { return script; } @Override public String multiplexValueSet(VariableEntity entity, Variable variable) { return multiplexVariable(variable); } @Override public String multiplexVariable(final Variable variable) { if(compiledScript == null) { throw new IllegalStateException("Script hasn't been compiled. Call initialise() before calling it."); } return (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())) { Value scriptableValue = scriptable.getValue(); return scriptableValue.isNull() ? null : scriptableValue.getValue(); } } return null; } }); } public String getScriptName() { return SCRIPT_NAME; } }