/* * Copyright 2015 Nabarun Mondal * 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.noga.njexl.spark.impl; import com.noga.njexl.lang.*; import com.noga.njexl.lang.Interpreter.AnonymousParam; import com.noga.njexl.lang.extension.TypeUtility; import java.io.Serializable; import java.util.List; import java.util.Map; import com.noga.njexl.lang.extension.oop.ScriptMethod; import scala.Tuple2; import scala.collection.Seq; import scala.reflect.ClassTag; /** * Created by noga on 07/11/15. */ public class ScalaInteract implements Serializable { public static final String MY_NAME = "$_" ; // java $cala bridge public static ClassTag $tag(Class<?> c) { return scala.reflect.ClassTag$.MODULE$.apply(c); } public static final ClassTag $TAG = $tag(Object.class); public static final Function1 $I = Function1.IDENTITY; public static final Function2 $I2 = Function2.IDENTITY; public static <T> scala.collection.immutable.List<T> $l(List<T> javaList) { return scala.collection.JavaConversions.asScalaIterable(javaList).toList(); } public static Tuple2 $t(Object o1, Object o2) { return new Tuple2(o1,o2); } public static Seq $s(Object o){ List l = TypeUtility.from(o); return $l(l); } public final String anonScript; public final boolean isMethod; transient Script script; transient ScriptMethod scriptMethod; transient Interpreter interpreter ; transient JexlContext context; public ScalaInteract(Object anon) { if (anon instanceof AnonymousParam ) { anonScript = Debugger.getText(((AnonymousParam)anon).block ); isMethod = false ; } else if ( anon instanceof ScriptMethod ){ anonScript = ((ScriptMethod)anon).definitionText ; isMethod = true ; }else { anonScript = ";"; isMethod = false ; } } protected Object safeCall(Object... args) { Object ret = Interpreter.NULL; Object o = args; if (args.length == 1) { o = args[0]; } if (script == null) { //set up... context = Main.getContext(); JexlEngine engine = Main.getJexl(context); context.set( ScalaInteract.MY_NAME , ScalaInteract.class ); Map m = Main.getFunction(context); engine.setFunctions(m); script = engine.createScript(anonScript); if ( isMethod ){ script.execute(context); scriptMethod = script.methods().values().iterator().next(); interpreter = ((ExpressionImpl)script).interpreter(); } } try { context.set(Script._ITEM_, o); if ( isMethod ){ ret = scriptMethod.invoke(this,interpreter, args ); }else { ret = script.execute(context); } } catch (Throwable e) { System.err.println("Error " + e.getMessage()); } return ret; } public static Object f(Object... args) { if (args.length == 0) { return Function1.IDENTITY; } if (!(args[0] instanceof AnonymousParam)) { return Function1.IDENTITY; } Object anon = args[0]; int numArgs = TypeUtility.castInteger(args[1], 0); switch (numArgs) { case 0: return new ScalaInteract.Function0(anon); case 1: return new ScalaInteract.Function1(anon); case 2: return new ScalaInteract.Function2(anon); } return Function1.IDENTITY; } public static AnonymousFunction.XFunction2 f2(Object... args) throws Exception { return new AnonymousFunction.XFunction2( (AnonymousParam)args[0] ) ; } public static class Function0 extends scala.runtime.AbstractFunction0 implements Serializable { public final ScalaInteract f; public Function0(Object a) { f = new ScalaInteract(a); } @Override public Object apply() { Object safe = f.safeCall(); if ( Interpreter.NULL == safe ) { throw new Error("Error applying Function0"); } return safe; } } public static class Function1 extends scala.runtime.AbstractFunction1 implements Serializable { public static final Identity IDENTITY = new Identity(); public final ScalaInteract f; public Function1(Object a) { f = new ScalaInteract(a); } @Override public Object apply(Object o) { Object safe = f.safeCall(o); if ( Interpreter.NULL == safe ) { throw new Error("Error applying Function1"); } return safe ; } public static final class Identity extends Function1 { private Identity() { super(null); } @Override public Object apply(Object o) { return o; } } } public static class Function2 extends scala.runtime.AbstractFunction2 implements Serializable { public static final Identity IDENTITY = new Identity(); public final ScalaInteract f; public Function2(Object a) { f = new ScalaInteract(a); } @Override public Object apply(Object o, Object o2) { Object safe = f.safeCall(o, o2); if ( Interpreter.NULL == safe ) { throw new Error("Error applying Function2"); } return safe; } public static final class Identity extends Function2 { private Identity() { super(null); } @Override public Object apply(Object o, Object o2) { return new Object[]{o, o2}; } } } }