How to implement Java interface anonymously in scala? - java

Suppose I have a Java inteface
public interface Bar {
public void baz(String st)
public void jaz()
}
I want to implement above interface anonymously in scala within a function body like:
def foo() = {
val bar : Bar = new Bar() {
// how to do that ?
}
}

If I had to, I'd write it as:
val bar = new Bar {
def baz(st: String): Unit = {
// method impl
}
def jaz(): Unit = {
// method impl
}
}
Though my preference is to avoid side-effecting methods as much as possible, they don't play very nicely with functional programming

val bar = new Bar {
def baz(st: String) {
// method impl
}
def jaz() {
// method impl
}
}

Related

Kotlin Flows Java Interop Callback

I´ve been looking for a suitable solution or best practice when I want to use Kotlin Flows with ordinary callbacks. My use case is that I write a kotlin library that uses Kotlin Flow internally and i have to assume that the users will use Java for instance. So I thought that the best solution is to overload a basic callback interface to my flow method and call it in collect something like this:
class KotlinClass {
interface Callback {
fun onResult(result: Int)
}
private fun foo() = flow {
for (i in 1..3) {
emit(i)
}
}
fun bar(callback: Callback) {
runBlocking {
foo().collect { callback.onResult(it) }
}
}
private fun main() {
bar(object : Callback {
override fun onResult(result: Int) {
TODO("Not yet implemented")
}
})
}
and in my Java Application i can simply use it like that:
public class JavaClass {
public void main() {
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(new KotlinClass.Callback() {
#Override
public void onResult(int result) {
// TODO("Not yet implemented")
}
});
}
}
I am not sure whats the way to go because I would like to have my Kotlin library that uses Flows usable in a good fashion for Java and Kotlin.
I came across callbackFlow but that seems to be only if I want to let´s call it flow-ify a callback-based API? Because I am quite new to Kotlin and Flows please apologise if my question is flawed in cause of missing some basic concepts of kotlin.
I would give the Java client more control over the flow. I would add a onStart and onCompletion method to your callback interface. Beside this I would use an own CoroutineScope - maybe customizable from the Java client. And I would not block the calling thread from within the Kotlin function - no runBlocking.
#InternalCoroutinesApi
class KotlinClass {
val coroutineScope = CoroutineScope(Dispatchers.Default)
interface FlowCallback {
#JvmDefault
fun onStart() = Unit
#JvmDefault
fun onCompletion(thr: Throwable?) = Unit
fun onResult(result: Int)
}
private fun foo() = flow {
for (i in 1..3) {
emit(i)
}
}
fun bar(flowCallback: FlowCallback) {
coroutineScope.launch {
foo().onStart { flowCallback.onStart() }
.onCompletion { flowCallback.onCompletion(it) }
.collect { flowCallback.onResult(it) }
}
}
fun close() {
coroutineScope.cancel()
}
}
Now the Java client is in full control how to start, collect and cancel the flow. For example you could use a latch to wait for completion, set an timeout and cancel the couroutine scope. This looks in the first place like a lot of code, but typically you will need this kind of flexibility.
public class JavaClass {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(new KotlinClass.FlowCallback() {
#Override
public void onCompletion(#Nullable Throwable thr) {
latch.countDown();
}
#Override
public void onResult(int result) {
System.out.println(result);
}
});
try {
latch.await(5, TimeUnit.SECONDS);
} finally {
libraryClass.close();
}
}
}
You don't need to create a interface in the Kotlin code. You can define bar like that:
fun bar(callback: (Int) -> Unit) {
runBlocking {
foo().collect { callback(it) }
}
}
From the Java code you can call the function like that:
public class JavaClass {
public static void main(String[] args) {
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(v -> { System.out.println(v); return Unit.INSTANCE; });
}
}
In case anyone wondering for a general solution. Here's our version of enhancement from #rene answer here.
Accept a generic type
A configurable coroutineScope
// JavaFlow.kt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
#InternalCoroutinesApi
class JavaFlow<T>(
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) {
interface OperatorCallback <T> {
#JvmDefault
fun onStart() = Unit
#JvmDefault
fun onCompletion(thr: Throwable?) = Unit
fun onResult(result: T)
}
fun collect(
flow: Flow<T>,
operatorCallback: OperatorCallback<T>,
) {
coroutineScope.launch {
flow
.onStart { operatorCallback.onStart() }
.onCompletion { operatorCallback.onCompletion(it) }
.collect { operatorCallback.onResult(it) }
}
}
fun close() {
coroutineScope.cancel()
}
}
Java caller-side:
// code omitted...
new JavaFlow<File>().collect(
// compressImageAsFlow is our actual kotlin flow extension
FileUtils.compressImageAsFlow(file, activity),
new JavaFlow.OperatorCallback<File>() {
#Override
public void onResult(File result) {
// do something with the result here
SafeSingleton.setFile(result);
}
}
);
// or using lambda with method references
// new JavaFlow<File>().collect(
// FileUtils.compressImageAsFlow(file, activity),
// SafeSingleton::setFile
// );
// Change coroutineScope to Main
// new JavaFlow<File>(CoroutineScopeKt.MainScope()).collect(
// FileUtils.compressImageAsFlow(file, activity),
// SafeSingleton::setFile
// );
OperatorCallback.onStart and OperatorCallback.onCompletion is optional, override it as needed.

Scala : Registry design pattern or similar?

I am migrating my system from java to Scala. I have used registry pattern in my java code to get the implementation from the string. Is there any similar thing I could do with scala ? I am new to scala, can someone point to me proper references ?
My java code :
public class ItemRegistry {
private final Map<String, ItemFactory> factoryRegistry;
public ItemRegistry() {
this.factoryRegistry = new HashMap<>();
}
public ItemRegistry(List<ItemFactory> factories) {
factoryRegistry = new HashMap<>();
for (ItemFactory factory : factories) {
registerFactory(factory);
}
}
public void registerFactory(ItemFactory factory) {
Set<String> aliases = factory.getRegisteredItems();
for (String alias : aliases) {
factoryRegistry.put(alias, factory);
}
}
public Item newInstance(String itemName) throws ItemException {
ItemFactory factory = factoryRegistry.get(itemName);
if (factory == null) {
throw new ItemException("Unable to find factory containing alias " + itemName);
}
return factory.getItem(itemName);
}
public Set<String> getRegisteredAliases() {
return factoryRegistry.keySet();
}
}
My Item interface :
public interface Item {
void apply(Order Order) throws ItemException;
String getItemName();
}
I map the string like :
public interface ItemFactory {
Item getItem(String itemName) throws ItemException;
Set<String> getRegisteredItems();
}
public abstract class AbstractItemFactory implements ItemFactory {
protected final Map<String, Supplier<Item>> factory = Maps.newHashMap();
#Override
public Item getItem(String alias) throws ItemException {
try {
final Supplier<Item> supplier = factory.get(alias);
return supplier.get();
} catch (Exception e) {
throw new ItemException("Unable to create instance of " + alias, e);
}
}
protected Supplier<Item> defaultSupplier(Class<? extends Item> itemClass) {
return () -> {
try {
return itemClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException("Unable to create instance of " + itemClass, e);
}
};
}
#Override
public Set<String> getRegisteredItems() {
return factory.keySet();
}
}
public class GenericItemFactory extends AbstractItemFactory {
public GenericItemFactory() {
factory.put("reducedPriceItem", () -> new Discount(reducedPriceItem));
factory.put("salePriceItem", () -> new Sale(reducedPriceItem));
}
}
where Sale and Discount are implemntation of Item. I use the newInstance method in ItemRegistry to get the class based on the name. Can some one suggest me any similar thing which can allow me to do the same in scala ?
The other answers give the following options:
Directly translate your existing Java code to Scala.
Implement another version of your existing code in Scala.
Use Spring for dependency injection.
This answer offers an approach that is different from the "registry pattern" and that uses the compiler instead of a string, or Spring, to resolve implementations. In Scala, we can use the language constructs to inject dependencies with the cake pattern. Below is an example using simplified versions of your classes:
case class Order(id: Int)
trait Item {
// renamed to applyOrder to disambiguate it from apply(), which has special use in Scala
def applyOrder(order: Order): Unit
def name: String
}
trait Sale extends Item {
override def applyOrder(order: Order): Unit = println(s"sale on order[${order.id}]")
override def name: String = "sale"
}
trait Discount extends Item {
override def applyOrder(order: Order): Unit = println(s"discount on order[${order.id}]")
override def name: String = "discount"
}
Let's define a class Shopping that depends on an Item. We can express this dependency as a self type:
class Shopping { this: Item =>
def shop(order: Order): Unit = {
println(s"shopping with $name")
applyOrder(order)
}
}
Shopping has a single method, shop, that calls both the applyOrder and name methods on its Item. Let's create two instances of Shopping: one that has a Sale item and one that has a Discount item...
val sale = new Shopping with Sale
val discount = new Shopping with Discount
...and invoke their respective shop methods:
val order1 = new Order(123)
sale.shop(order1)
// prints:
// shopping with sale
// sale on order[123]
val order2 = new Order(456)
discount.shop(order2)
// prints:
// shopping with discount
// discount on order[456]
The compiler requires us to mix in an Item implementation when creating a Shopping instance. We have compile-time enforcement of the dependencies, and we don't need third-party libraries, with this pattern.
You can pretty much just translate your Java classes to Scala and use the exact same pattern as you're doing in Java.
Since Scala runs on the JVM you can also use it with Spring. It may not be the "standard" way of writing services in Scala but it's definitely a viable choice.
As others have already suggested, you can translate your code directly into Scala without changing the design pattern, if that's what you want.
Here's how that might look:
import scala.collection.Set
import scala.collection.mutable
import scala.collection.immutable
trait Item
trait ItemFactory {
def registeredItems: Set[String]
def getItem(alias: String): Item
}
class ItemRegistry(factories: List[ItemFactory]) {
final private val factoryRegistry = mutable.Map[String, ItemFactory]()
factories.foreach(this.registerFactory)
def registerFactory(factory: ItemFactory): Unit = {
factory.registeredItems.foreach(alias =>
factoryRegistry.put(alias, factory))
}
def newInstance(itemName: String): Item = {
val factory = this.factoryRegistry.get(itemName)
.getOrElse(throw new Exception("Unable to find factory containing alias " + itemName))
factory.getItem(itemName)
}
def getRegisteredAliases: Set[String] = this.factoryRegistry.keySet
}
I would suggest that this is a clunky pattern in both Java and Scala though. It may be useful from time to time.
Could you give an example of what you want to achieve with this? When do you need to use a different factory based on a runtime value?

How to mock methods/functions provided by Traits in Groovy

Here's an example:
trait Sender {
def send(String msg){
// do something
}
}
class Service implements Sender {
def myMethod1(){
send('Foo')
myMethod2()
}
def myMethod2(){
}
}
I am trying to test the Service class. However, I would like to stub/mock the calls to the methods provided by the trait (send)?
I have tried several different ways to stub/mock the method send, with no success:
// 1
Service.metaclass.send = { String s -> // do nothing }
// 2
def service = new MyService()
service.metaClass.send = { String s -> // do nothing }
// 3
StubFor serviceStub = new StubFor(Service.class)
serviceStub.demand.send { String s -> // do nothing }
//
trait MockedSender {
def send(String msg) { // do nothing }
}
def service = new Service() as MockedSender
These are just some of the things I tried. I even tried using Mock frameworks like Mockito. Unfortunately, nothing seems to work. Any suggestions???
Try using Spy from Spock framework!
Like this:
trait Sender {
def send(String msg){
println msg
}
}
class Service implements Sender {
def myMethod1(){
send('Foo')
myMethod2()
}
def myMethod2(){
println 'real implementation'
}
}
class UnitTest extends Specification {
def "Testing spy on real object"() {
given:
Service service = Spy(Service)
when:
service.myMethod1()
then: "service.send('Foo') should be called once and should print 'mocked' and 'real implementation' on console"
1 * service.send('Foo') >> { println 'mocked' }
}
}

AOP for Groovy via closures and pattern matching?

I have an abstract base POGO:
abstract class AuthorizingResource {
void authorize(String credential) {
if(!credentialIsValid(credential)) {
throw new AuthorizationException(credential)
}
}
boolean credentialIsValid(String credential) {
// Do stuff to determine yea or nay
}
}
And many concrete subclasses like so:
class FizzResource extends AuthorizingResource {
List<Fizz> getAllFizzes(String credential) {
authorize(credential)
List<Fizz> fizzes
// Do stuff
fizzes
}
Fizz getFizzById(String credential, Long id) {
authorize(credential)
Fizz fizz
// Do stuff
fizz
}
void considerTheLillies(Buzz buzz) {
// Do stuff
}
void upsertFizz(String credential, Fizz fizz) {
authorize(credential)
// Do stuff
}
}
As you can see there's several things going on:
Any FizzResource methods that I want authenticated/authorized, I need to manually call authorize(...) at the top of the method
Some methods (considerTheLillies) do not need to be authed
I was wondering if I could mimic AOP by using a closure to call authorize(...) (so I don't have to keep adding it mindlessly) that can use some sort of pattern for selecting which methods to "wrap" inside the closure. In the particular case of the FizzResource, this would be any method that contains "*Fizz*" in it, but that pattern should be (ideally) any valid regex. The one thing that can't change is that any method that accepts credential arg cannot have its signature modified.
So basically, something like Spring AOP or Google Guice's method interceptors, but using native Groovy closures.
Any ideas?
You can use invokeMethod with GroovyInterceptable. Note that any fizz in the name will be matched:
abstract class AuthorizingResource implements GroovyInterceptable {
def invoked = []
def validator = [credentialIsValid : { true }]
void authorize(String credential) {
if ( !validator.credentialIsValid(credential) ) {
throw new RuntimeException(credential)
}
}
def invokeMethod(String method, args) {
if (method.toLowerCase().contains('fizz')) {
metaClass.getMetaMethod('authorize', String).invoke(this, args[0])
invoked.add( 'authorized ' + method )
}
return metaClass
.getMetaMethod(method, args*.getClass() as Class[])
.invoke(this, args)
}
}
class Fizz { String name }
class FizzResource extends AuthorizingResource {
List<Fizz> getAllFizzes(String credential) { ['all fizzes'] }
Fizz getFizzById(String credential, Long id) { new Fizz(name: 'john doe') }
def considerTheLillies() { 42 }
}
res = new FizzResource()
assert res.getAllFizzes('cred') == ['all fizzes']
assert res.considerTheLillies() == 42
assert res.getFizzById('cred', 10l).name == 'john doe'
assert res.invoked == ['authorized getAllFizzes', 'authorized getFizzById']
I couldn't stop thinking about a closure based solution. I came up with some Javascript style code, using closures and maps. It features no inheritance:
class AuthorizingResource {
void authorize(String credential) {
if(!credentialIsValid(credential)) {
throw new RuntimeException(credential)
}
}
boolean credentialIsValid(String credential) { true }
}
class Fizz {}
abstract class FizzResource {
abstract List<Fizz> getAllFizzes(String credential)
abstract int getFizzById(String credential, Long id)
abstract void considerTheLillies(buzz)
static createFizzResource(authorized) {
def auth = new AuthorizingResource()
def authorize = { auth.authorize it; authorized << it }
return [
getAllFizzes : { String credential -> ['fizz list'] },
getFizzById : { String credential, Long id -> 42 },
considerTheLillies : { buzz -> }
]
.collectEntries { entry ->
entry.key.toLowerCase().contains('fizz') ?
[(entry.key) : { Object[] args ->
authorize(args[0]); entry.value(*args)
}] :
entry
} as FizzResource
}
}
Testing:
def authorized = []
def fizz = FizzResource.createFizzResource(authorized)
assert authorized == []
assert fizz.getAllFizzes('getAllFizzes cred') == ['fizz list']
fizz.considerTheLillies null
assert authorized == ['getAllFizzes cred']
assert fizz.getFizzById('fizz by id cred', 90l) == 42
assert authorized == ['getAllFizzes cred', 'fizz by id cred']
Note the authorized list is very dumb, and only needed for assert purposes.

Creating a Class with specific methods in Java

I have 10 specific methods on my code, and I want to use them with a Class Object like this one:
void function(){
//do Something that I want
}
class PoseAction{
Pose pose;
void methodDesirable();
PoseAction(Pose ps, Method function()){
this.pose = ps;
this.methodDesirable() = function();
}
}
So when I create a new Object
PoseAction ps = new PoseAction(pose1, action1());
calling
ps.methodDesirable();
it will call action1() function.
It's possible to do this?
Thanks in advance!
Functions are not first class objects in java. That is, you can not directly assign them or pass them as method parameters. You need to use objects and interfaces:
interface Action {
void fire(Pose pose);
}
class PoseAction {
Action action;
Pose pose;
void methodDesirable() {
action.fire(pose)
}
PoseAction(Pose ps, Action a) {
pose = ps;
action = a;
}
}
And use it like:
PoseAction ps = new PoseAction(pose1, new Action() {
public void fire(Pose pose) {
action1(pose);
}
};
ps.methodDesirable();
No it's not possible in such way, Java doesn't support delegates. In java that can be done with interfaces:
interface Command {
void doCommand();
}
PoseAction pa = new PoseAction(new Pose(), new Command() {
#Override
public void doCommand() {
//method body
}
});
Here new Command() {...} is anonymous inner class that implements Command Interface

Categories

Resources