How is the best way to map UsbConfiguration object in Kotlin? - android-studio

Hello actually I'm developing an app with the use of USB, I need return the UsbConfiguration from this map structure but the compiler error is:
Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly
This is the call from the method:
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun getConfiguration(index:Int?):
Map<String, Any> {
val device = usbDevice
val configuration: UsbConfiguration = device!!.getConfiguration(index!!)
val map = configuration.toMap() + ("index" to index)
return map
}
And this is the part with the problem specific in getInterface(it).toMap():
fun UsbConfiguration.toMap() = mapOf(
"id" to id,
"interfaces" to List(interfaceCount) {
getInterface(it).toMap() }
)
The code from library to the method getInterface(int index)
#NonNull
public UsbInterface getInterface(int index) {
throw new RuntimeException("Stub!");
}

Related

When extending an interface, should we use object keyword?

I have two different pieces of code. In one i need to use object and in the second i'm not.
Can someone explain me the difference between the situation:
first Code:
private val onInitWebResponseHandler: VolleyHandler.WebResponseHandler = VolleyHandler.WebResponseHandler()
{
Thread(ParseJsonStringOnInit(WeakReference(this),
weakRefIOnAllScoresDataFirstFetched, it)).start()
}
Second Code:
val competitionOrderLevelComparator : Comparator<CompetitionObj> = object : Comparator<CompetitionObj> {
override fun compare(object1: CompetitionObj, object2: CompetitionObj): Int
{
return object1.orderLevel - object2.orderLevel
}
}
fun interface WebResponseHandler
{
fun onWebResponseFinished(jsonString:String?)
}
In addition how the first code, we can have () brackets if interface doesn't have a constructor?

Empty set after collectAsList, even though it is not empty inside the transformation operator

I am trying to figure out if I can work with Kotlin and Spark,
and use the former's data classes instead of Scala's case classes.
I have the following data class:
data class Transaction(var context: String = "", var epoch: Long = -1L, var items: HashSet<String> = HashSet()) :
Serializable {
companion object {
#JvmStatic
private val serialVersionUID = 1L
}
}
And the relevant part of the main routine looks like this:
val transactionEncoder = Encoders.bean(Transaction::class.java)
val transactions = inputDataset
.groupByKey(KeyExtractor(), KeyExtractor.getKeyEncoder())
.mapGroups(TransactionCreator(), transactionEncoder)
.collectAsList()
transactions.forEach { println("collected Transaction=$it") }
With TransactionCreator defined as:
class TransactionCreator : MapGroupsFunction<Tuple2<String, Timestamp>, Row, Transaction> {
companion object {
#JvmStatic
private val serialVersionUID = 1L
}
override fun call(key: Tuple2<String, Timestamp>, values: MutableIterator<Row>): Transaction {
val seq = generateSequence { if (values.hasNext()) values.next().getString(2) else null }
val items = seq.toCollection(HashSet())
return Transaction(key._1, key._2.time, items).also { println("inside call Transaction=$it") }
}
}
However, I think I'm running into some sort of serialization problem,
because the set ends up empty after collection.
I see the following output:
inside call Transaction=Transaction(context=context1, epoch=1000, items=[c])
inside call Transaction=Transaction(context=context1, epoch=0, items=[a, b])
collected Transaction=Transaction(context=context1, epoch=0, items=[])
collected Transaction=Transaction(context=context1, epoch=1000, items=[])
I've tried a custom KryoRegistrator to see if it was a problem with Kotlin's HashSet:
class MyRegistrator : KryoRegistrator {
override fun registerClasses(kryo: Kryo) {
kryo.register(HashSet::class.java, JavaSerializer()) // kotlin's HashSet
}
}
But it doesn't seem to help.
Any other ideas?
Full code here.
It does seem to be a serialization issue.
The documentation of Encoders.bean states (Spark v2.4.0):
collection types: only array and java.util.List currently, map support is in progress
Porting the Transaction data class to Java and changing items to a java.util.List seems to help.

I need generic way to filter IQueryable data and filters are populated as dictionary

I need generic way to filter IQueryable data and filters are populated as dictionary. I have already created method like this.
public static IEnumerable<T> CustomApplyFilter<T>(this IQueryable<T> source, Dictionary<string, string> filterBy)
{
foreach (var key in filterBy.Keys)
{
source.Where(m => m.GetType().GetProperty(key).GetValue(m, null).Equals(filterBy[key]));
}
return source.ToList();
}
But its always returning same result.
please find the caller
Dictionary<string, string> dtFilter = new Dictionary<string, string>();
dtFilter.Add("Id", "2");
var res = context.Set<MyEntity>().CustomApplyFilter<MyEntity>(dtFilter);
The Where extension method does not change the content of the IQueryable it is applied to. The return value of the method should be used:
public static IEnumerable<T> CustomApplyFilter<T>(this IQueryable<T> source, Dictionary<string, string> filterBy)
{
foreach (var key in filterBy.Keys)
{
source = source.Where(m => m.GetType().GetProperty(key).GetValue(m, null).Equals(filterBy[key]));
}
return source.ToList();
}
UPDATE:
I should have noticed it, my answer so far was applicable to LINQ to Objects only. When using LINQ to Entities, however, there are certain restrictions; only expression that can be converted to an SQL query can be used. Getting properties through reflection is not such an expression obviously.
When this is the case, one possible solution would be to build the ExpressionTree manually.
public static IEnumerable<T> CustomApplyFilter<T>(this IQueryable<T> source, Dictionary<string, string> filterBy)
{
foreach (var key in filterBy.Keys)
{
var paramExpr = Expression.Parameter(typeof(T), key);
var keyPropExpr = Expression.Property(paramExpr, key);
var eqExpr = Expression.Equal(keyPropExpr, Expression.Constant(filterBy[key]));
var condExpr = Expression.Lambda<Func<T, bool>>(eqExpr, paramExpr);
source = source.Where(condExpr);
}
return source.ToList();
}
UPDATE2:
With the comment #Venkatesh Kumar given below, it is apparent that when the underlying type of the field provided is not of type string, this solution fails (with the error message : The binary operator Equal is not defined for the types 'System.Int64' and 'System.String').
One possible way to tackle this problem would be to have a dictionary of types and delegates to use for each such property.
Since this is a static method (an extension method which has to be static), declaring a static Dictionary in class scope would be reasonable:
Let's assume the name of the class in which CustomApplyFilter is declared is SOFExtensions:
internal static class SOFExtensions
{
private static Dictionary<Type, Func<string, object>> lookup = new Dictionary<Type, Func<string, object>>();
static SOFExtensions()
{
lookup.Add(typeof(string), x => { return x; });
lookup.Add(typeof(long), x => { return long.Parse(x); });
lookup.Add(typeof(int), x => { return int.Parse(x); });
lookup.Add(typeof(double), x => { return double.Parse(x); });
}
public static IEnumerable<T> CustomApplyFilter<T>(this IQueryable<T> source, Dictionary<string, string> filterBy)
{
foreach (var key in filterBy.Keys)
{
var paramExpr = Expression.Parameter(typeof(T), key);
var keyPropExpr = Expression.Property(paramExpr, key);
if (!lookup.ContainsKey(keyPropExpr.Type))
throw new Exception("Unknown type : " + keyPropExpr.Type.ToString());
var typeDelegate = lookup[keyPropExpr.Type];
var constantExp = typeDelegate(filterBy[key]);
var eqExpr = Expression.Equal(keyPropExpr, Expression.Constant(constantExp));
var condExpr = Expression.Lambda<Func<T, bool>>(eqExpr, paramExpr);
source = source.Where(condExpr);
}
return source.ToList();
}
}
Other types and proper delegates for them should be added to the lookup Dictionary as required.

Kotlin thread safe native lazy singleton with parameter

In java we can write thead-safe singletons using double Checked Locking & volatile:
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance(String arg) {
Singleton localInstance = instance;
if (localInstance == null) {
synchronized (Singleton.class) {
localInstance = instance;
if (localInstance == null) {
instance = localInstance = new Singleton(arg);
}
}
}
return localInstance;
}
}
How we can write it in kotlin?
About object
object A {
object B {}
object C {}
init {
C.hashCode()
}
}
I used kotlin decompiler to get that
public final class A {
public static final A INSTANCE;
private A() {
INSTANCE = (A)this;
A.C.INSTANCE.hashCode();
}
static {
new A();
}
public static final class B {
public static final A.B INSTANCE;
private B() {
INSTANCE = (A.B)this;
}
static {
new A.B();
}
}
public static final class C {
public static final A.C INSTANCE;
private C() {
INSTANCE = (A.C)this;
}
static {
new A.C();
}
}
}
All of object have constructor invoke in static block. Based on it, we can think that it's not lazy.
Сlose to the right answer.
class Singleton {
companion object {
val instance: Singleton by lazy(LazyThreadSafetyMode.PUBLICATION) { Singleton() }
}
}
Decompiled:
public static final class Companion {
// $FF: synthetic field
private static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.property1(new PropertyReference1Impl(Reflection.getOrCreateKotlinClass(Singleton.Companion.class), "instance", "getInstance()Lru/example/project/tech/Singleton;"))};
#NotNull
public final Singleton getInstance() {
Lazy var1 = Singleton.instance$delegate;
KProperty var3 = $$delegatedProperties[0];
return (Singleton)var1.getValue();
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
I hope Kotlin developers will make non reflection implementation in future...
Kotlin has an equivalent of your Java code, but more safe. Your double lock check is not recommended even for Java. In Java you should use an inner class on the static which is also explained in Initialization-on-demand holder idiom.
But that's Java. In Kotlin, simply use an object (and optionally a lazy delegate):
object Singletons {
val something: OfMyType by lazy() { ... }
val somethingLazyButLessSo: OtherType = OtherType()
val moreLazies: FancyType by lazy() { ... }
}
You can then access any member variable:
// Singletons is lazy instantiated now, then something is lazy instantiated after.
val thing = Singletons.something // This is Doubly Lazy!
// this one is already loaded due to previous line
val eager = Singletons.somethingLazyButLessSo
// and Singletons.moreLazies isn't loaded yet until first access...
Kotlin intentionally avoids the confusion people have with singletons in Java. And avoids the "wrong versions" of this pattern -- of which there are many. It instead provides the simpler and the safest form of singletons.
Given the use of lazy(), if you have other members each would individually be lazy. And since they are initialized in the lambda passed to lazy() you can do things that you were asking about for about customizing the constructor, and for each member property.
As a result you have lazy loading of Singletons object (on first access of instance), and then lazier loading of something (on first access of member), and complete flexibility in object construction.
See also:
lazy() function
Lazy thread safe mode options
Object declarations
As a side note, look at object registry type libraries for Kotlin that are similar to dependency injection, giving you singletons with injection options:
Injekt - I'm the author
Kodein - Very similar and good
Object declaration is exactly for this purpose:
object Singleton {
//singleton members
}
It is lazy and thread-safe, it initializes upon first call, much as Java's static initializers.
You can declare an object at top level or inside a class or another object.
For more info about working with objects from Java, please refer to this answer.
As to the parameter, if you want to achieve exactly the same semantics (first call to getInstance takes its argument to initialize the singleton, following calls just return the instance, dropping the arguments), I would suggest this construct:
private object SingletonInit { //invisible outside the file
lateinit var arg0: String
}
object Singleton {
val arg0: String = SingletonInit.arg0
}
fun Singleton(arg0: String): Singleton { //mimic a constructor, if you want
synchronized(SingletonInit) {
SingletonInit.arg0 = arg0
return Singleton
}
}
The main flaw of this solution is that it requires the singleton to be defined in a separate file to hide the object SingletonInit, and you cannot reference Singleton directly until it's initialized.
Also, see a similar question about providing arguments to a singleton.
I recently wrote an article on that topic.
TL;DR Here's the solution I came up to:
1) Create a SingletonHolder class. You only have to write it once:
open class SingletonHolder<out T, in A>(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
#Volatile private var instance: T? = null
fun getInstance(arg: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(arg)
instance = created
creator = null
created
}
}
}
}
2) Use it like this in your singletons:
class MySingleton private constructor(arg: ArgumentType) {
init {
// Init using argument
}
companion object : SingletonHolder<MySingleton, ArgumentType>(::MySingleton)
}
The singleton initialization will be lazy and thread-safe.

Generic Method with generic return

Well, I have the following scenario:
public class Joins<TOuter, TInner, TResult>
{
public Expression<Func<TOuter, object>> outerKeySelector;
public Expression<Func<TInner, object>> innerKeySelector;
public Expression<Func<TOuter, TInner, object>> resultSelector;
public IEnumerable<TResult> r;
}
public class Test<T>
{
public IEnumerable<TResult> Join<TInner, TResult>(
Expression<Func<T, object>> outerKeySelector,
Expression<Func<TInner, object>> innerKeySelector,
Expression<Func<T, TInner, TResult>> resultSelector) where TInner : class
{
var join = new Joins<T, TInner, TResult>();
join.innerKeySelector = innerKeySelector;
join.outerKeySelector = outerKeySelector;
return join.r;
}
}
To create the join method, I relied on the link: http://msdn.microsoft.com/en-us/library/bb534644(v=vs.100).aspx
However, when I try to invoke the method, TInner is not recognized, making the method becomes invalid me returning the following error:
Cannot convert expression type 'type' to return type 'TResult'
Note: The class 'Joins' is purely a test, none of it is definitive and the var 'r' is for testing only, used only to facilitate the return.
Example of intended use:
var test = new Test<User>().Join<Permission>(u => u.Id, p => p.IdUser, (u, p) => new { Id = u.Id , Area = p.Area });
More details:
As mentioned, TInner is not recognized, so I can not make a call the correct method.
As a test I did so:
var test = new Test<User>().Join<Permission>(u => u.Id, p => p.ToString(), (u, p) => new {Id = u.Id, Name = p.ToString()});
I know p.ToString() is not correct, but is not recognizing the properties of the class indicated (in the case Permission), then put ToString() just to finish writing the method.
EDIT:
I need to use the result in a foreach/for
example:
foreach(var obj in test)
{
var id = obj.Id;
var area = obj.Area;
.
.
.
}
To make it work, you should do the following:
var test = new Test<User>().Join<Permission, object>(u => u.Id, p => p.IdUser, (u, p) => new { Id = u.Id, Area = p.Area });
// ^^ (resolve the second type argument as well)
When you define the following:
public TResult Join<TInner, TResult>
then you should either give compiler a hint which type there will be (instead of any, mentioned as type argument: TInner, TResult) explicitly, or it must be somehow recognized automatically by compiler (and then you can ommit it from explicit definition), but in your case you must do that explicitly.
Have a look of this answer. Even though that question is also related to extension methods, there is a pretty good explanation of the logic with the type arguments to resolve.
EDIT:
But object, for sure, is not the best decision, as you can not do anything with that object later (especially, if that's an anonymous type).
So, you should change it, for instance, in the following way:
public class Test<T, TInner> where TInner : class where T : class
{
public IEnumerable<TResult> Join<TResult>(
...
Expression<Func<T, TInner, TResult>> resultSelector)
after that you can use it as follows:
var test = new Test<User, Permission>()
.Join(u => u.Id, p => p.IdUser, (u, p) => new { Id = u.Id, Area = p.Area });
EDIT:
if you need the TInner and TResult to be passed to Join method, that's not really possible. The anonymous class can be resolved only automatically by compiler - you can not specify it explicitly.
So, the only way you can solve it then, as the following:
var test = new Test<User>().Join<Permission, dynamic>(...
that would allow you to use your result then with LinQ .Where( method, however, without intellisense support (unless, you create a concrete class for the Join output).

Resources