I'm trying to convert following java snippet to Xtend, but i couldn't able to do it. I'm not able to access static property 'class'.
public class SyncService{
private static final String LOGT = SyncService.class.getSimpleName();
}
I tried following methods,
class SyncService {
val LOGT = SyncService.class.getSimpleName();
}
class SyncService {
val LOGT = SyncService::class.getSimpleName();
}
According to the documentation it's
SyncService.simpleName
or with the legacy syntax:
typeof(SyncService).simpleName
Related
I have my code structure like this:
File 1:
abstract class SomeClass {
abstract fun print()
companion object {
val versions = arrayOf(ClassV1::class, ClassV2::class)
}
}
#Serializable
data class ClassV1(val x: Int) : SomeClass() {
override fun print() {
println("Hello")
}
}
#Serializable
data class ClassV2(val y: String) : SomeClass() {
override fun print() {
println("World")
}
}
File 2:
fun <T : SomeClass> getSomeObject(json: String, kClass: KClass<T>): SomeClass {
return Json.decodeFromString(json)
}
fun printData(version: Int, json: String) {
val someClass: SomeClass = getSomeObject(json, SomeClass.versions[version])
someClass.print()
}
I have a json in printData that is a serialized form of some sub-class of SomeClass. I also have a version which is used to determine which class structure does the json represent. Based on the version, I want to de-serialize my json string to the appropriate sub-class of SomeClass.
Right now the getSomeObject function deserializes the json to SomeClass (which crashes, as expected). I want to know if there is a way I can deserialize it to the provided KClass.
I know I can do this like below:
val someClass = when (version) {
0 -> Json.decodeFromString<ClassV1>(json)
else -> Json.decodeFromString<ClassV2>(json)
}
But I am trying to avoid this since I can have a lot of such versions. Is there a better way possible?
It seems to me that the following is what you are looking for:
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "version",
visible = false)
#JsonSubTypes(
JsonSubTypes.Type(value = ClassV1::class, name = "V1"),
JsonSubTypes.Type(value = ClassV2::class, name = "V2"))
abstract class SomeClass {
(...)
}
This basically means that your JSON would be deserialized as ClassV1 or ClassV2 based on the JSON property version:
V1 would mean that ClassV1 is the target class;
V2 would mean that ClassV2 is the target class.
You can find more information about this at the following online resources:
https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html
https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonSubTypes.Type.html
https://www.baeldung.com/jackson-annotations#jackson-polymorphic-type-handling-annotations
I have an integration test that needs to call a REST service to get an access token one time before any subsequent tests are run. Before adding Koin to my project, I accomplished this in a static method annotated with #BeforeClass like so:
class PersonRepositoryIntegrationTest {
companion object {
private var _clientToken: String? = null
#BeforeClass
#JvmStatic
fun setup() {
_clientToken = AuthRepository().getClientToken()!!.accessToken
}
}
#Test
fun testCreatePerson() {
PersonRepository().createPerson(_clientToken)
}
AuthRepository and PersonRepository have additional dependencies that up until now were instantiated in their constructors. Now, I want to use Koin to resolve these dependencies by injecting the repositories:
class PersonRepositoryIntegrationTest : KoinTest {
companion object {
private val _authRepository by inject<IAuthRepository>()
private val _personRepository by inject<IPersonRepository>()
private var _clientToken: String? = null
#BeforeClass
#JvmStatic
fun beforeClass() {
startKoin(listOf(AppModule.appModule))
_clientToken = _authRepository.getClientToken()!!.accessToken
}
}
When I try to use inject inside the companion object, the compiler gives an error:
Unresolved reference.
None of the following candidates is applicable because of receiver type mismatch.
* public inline fun <reified T : Any> KoinComponent.inject(name: String = ..., scope: Scope? = ..., noinline parameters: ParameterDefinition = ...): Lazy<IAuthRepository> defined in org.koin.standalone
Is there another way I can use Koin to inject my classes in a #BeforeClass static method like this?
According to kotlin documentation, companion objects are technically real objects.
even though the members of companion objects look like static members
in other languages, at runtime those are still instance members of
real objects, and can, for example, implement interfaces:
If a class wants to inject dependencies and it is not one of the koin supported classes(Activity, Fragment, ViewModel, KoinTest etc), then that class should implement the KoinComponent interface.
So consider changing your companion object definition to the following and try again.
companion object : KoinComponent{
private val _authRepository by inject<IAuthRepository>()
private val _personRepository by inject<IPersonRepository>()
private var _clientToken: String? = null
#BeforeClass
#JvmStatic
fun beforeClass() {
startKoin(listOf(AppModule.appModule))
_clientToken = _authRepository.getClientToken()!!.accessToken
}
In addition to the accepted answer, I discovered that I can use the inject method from org.koin.java.standalone.KoinJavaComponent, documented here:
import org.koin.java.standalone.KoinJavaComponent.inject
class PersonRepositoryIntegrationTest : KoinTest {
companion object {
private val _authRepository by inject(IAuthRepository::class.java)
private val _personRepository by inject(IPersonRepository::class.java)
private var _clientToken: String? = null
#BeforeClass
#JvmStatic
fun beforeClass() {
startKoin(listOf(AppModule.appModule))
_clientToken = _authRepository.getClientToken()!!.accessToken
}
}
This seems strange to me because I'm using Java interop methods in a Kotlin class, so I'd prefer to solve the problem by changing my companion object to extend KoinComponent instead as recommended here.
I have the following class:
class People
{
private List<String> people = new ArrayList<>();
public People()
{
people.add("Jhon");
people.add("Rose");
}
}
it is serialized using jackson to {"people":["Jhon","Rose"]}
I would like to serialize to ["Jhon","Rose"] without custom serializers.
any suggestion?
any help will be appreciated!
The simplest way would be to get the field and serialize that instead of the wrapper object:
People people = new People();
String json = mapper.writeValueAsString(people.getPeople());
If that's not an option, a Converter may be simpler than a custom serializer:
class PeopleToList extends StdConverter<People, List<String>> {
#Override public List<String> convert(People people) {
return people.getPeople();
}
}
and specify to use that:
#JsonSerialize(converter = PeopleToList.class)
class People {
My application has configurations which are loaded using parsing annotations into a file using Jackson's fasterxml annotations. For example:
public class RootConfiguration extends Configuration {
#JsonProperty
#NotEmpty
public String foo;
#JsonProperty
public BarConfiguration bar;
public class BarConfiguration extends Configuration {
#JsonProperty
public String baz;
}
}
The configuration is then injected into providers in my Module that help me bind those properties to places in the code that use them. Like so:
#Provides
#Named("config")
public RootConfiguration provideRootConfiguration(RootConfiguration configuration) {
return configuration;
}
#Provides
#Named("config.foo")
public String provideFooConfiguration(RootConfiguration configuration) {
return configuration.foo;
}
#Provides
#Named("config.bar")
public BarConfiguration provideBarConfiguration(RootConfiguration configuration) {
return configuration.bar;
}
And so on.
I'm looking for a framework to help me avoid this tedious work.
I would imagine something that looks like this:
#Configuration(value = "config", bindSubProperties = true)
public class RootConfiguration extends Configuration {
...
That would use Reflection to bind any sub fields in my class as guice Names.
I've looked into Governator's annotations for configurations but as far as I can see they need to be applied to every configuration that I want to bind, which saves me some coding, but is essentially the same (I still have to manually specify the path for each and every configuration I want to bind).
Before I roll out my own implementation for this, is there something that will give me what I need?
Note: I'm using this for a Dropwizard project so the constraint on using Jackson to map the configuration to POJOs is rather tight (unless I move the application configuration outside of the config yaml).
I don't know of any tool that would do this for you, but you could do it yourself pretty easily with something like this:
void bindConfiguration() {
for (Field field : RootConfiguration.class.getFields() {
bindConfiguration(TypeLiteral.get(field.getGenericType()), field);
}
}
<T> void bindConfiguration(TypeLiteral<T> type, Field field) {
bind(type)
.annotatedWith(Names.named("config." + field.getName()))
.toProvider(new ConfigurationProvider<T>(field))
.in(Singleton.class);
}
class ConfigurationProvider<T> implements Provider<T> {
private final Field field;
#Inject RootConfiguration configuration;
ConfigurationProvider(Field field) {
this.field = field;
}
#Override
public T get() {
return (T) field.get(configuration);
}
}
I have the following code.
public class SomeClass {
private List<SomeOtherClass> referrals;
public List<SomeOtherClass> getReferrals() {
return referrals;
}
public void setReferrals( List<SomeOtherClass> referrals) {
this.referrals = referrals;
}
}
I have a json that I read from the wire. It is correctly formatted. I use GSON
My question is :
when I do fromJson(jsonString,SomeClass.class);
it gives an exception.
If I don't use List<SomeOtherClass> but instead use List<String> for referrals.
(in other word a primitive)
And iterate over each String and create SomeOtherClass object it works fine.
Why can't I just use fromJson(jsonString,SomeClass.class);