Reputation: 307
I am new to Scala and I need to have a scala wrapper for my Java API
I have three Java Interfaces
public interface Client<T> {
<T> Future<T> execute(App<T> app);
}
public interface App<T> extends Serializable{
T process(AppContext context) throws Exception;
}
public interface AppContext {
File getDirectory();
void deleteDirectory();
File createDirectory(String path);
}
Following is the Java code to create an App
public class RandomApp extends App<String> {
@Override
public String process(AppContext context) {
// Inorder to access the methods in AppContext I need to access
// it by the following way
appContext.createDirectory("some path");
return "random";
}
}
I want to have a Scala Wrapper for the Client Interface which in turn call the Java API. But I have some modifications for the new Scala API
object ScalaConverter {
implicit class ScalaWrapper(client: Client) {
def scalaClient = new ScalaClient(client)
}
}
class ScalaClient(client: Client) {
def execute[T](appContext: AppContext => T): Future[T] = {
// I am passing appContext as closure instead of passing in
// App because I want to take the advantage of Closures in Scala
// I basically want to create an App with this appContext and
// pass it to the execute method
// For example - but this is not working
var app = // Need to create this app with appContext
Future {
client.execute(app)
}
}
}
Upvotes: 0
Views: 1212
Reputation: 1115
If I'm not mistaken, you just want to be able to create App objects from a function that takes a AppContext as parameter and returns a any object (let's say T).
As it's not really interesting to try to mirror the whole java API, just use it as it is, but add some extensions. And to do this you should use implicits.
To do this, I see two possibilities: either add an implicit class on the Client
interface to add some functions to it, or add an implicit conversion from (AppContext => T)
to App
objects.
Let's got with the first solution, you have to embed the implicit class in an object (this can be a package object if you need automatic imports).
object ScalaConverter {
class ScalaApp[T](val block: AppContext => T) extends App[T] {
def process(context: AppContext): T = block(context)
}
implicit class ScalaClient(client: Client) extends AnyVal{
def execute[T](block: AppContext => T): Future[T] = {
client.execute(new ScalaApp(block))
}
}
}
Then, you just have to use your existing java Client object:
import ScalaConverter._
myJavaClient.execute { context =>
???
}
You should get the principle, I maybe made a mistake (did not tried to compile this)
Upvotes: 2