Help with "secondary" constructors


#1

How I can convert this Java class to Kotlin?

import java.util.Collection;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

public final class DomainUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
  private final String domain;

  public DomainUsernamePasswordAuthenticationToken(String principal, String credentials, String domain) {
  super(principal, credentials);
  this.domain = domain;
  }

  public DomainUsernamePasswordAuthenticationToken(CalendarUser principal, String credentials, String domain,
           Collection<? extends GrantedAuthority> authorities) {
  super(principal, credentials, authorities);
  this.domain = domain;
  }

  public String getDomain() {
  return domain;
  }

  private static final long serialVersionUID = -5138870746127783L;
}


#2

Try this:

``

import java.util.Collection;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

public class DomainUsernamePasswordAuthenticationToken(
  principal: CalendarUser,
  credentials: String,
  val domain: String,
  authorities: Collection<out GrantedAuthority>? = null
) : UsernamePasswordAuthenticationToken(principal, credentials, authorities) {

  {
  if (authorities == null) {
           super.setAuthenticated(false)
  }
  }

  private val serialVersionUID = -5138870746127783
}


#3

The problem whit this approach, is that "principal" parameter have type String in one constructor and CalendarUser in other, surely I could use Any as parameter, cause' the super constructor take a Object as parameter, but this is not a corner case and must be addressed.

The “Java to Kotlin” feature that come with the plugin produce some “init” functions inside the class object but this code is imposible to compile


#4

The standard way of creating "secondary constructors" is this:

``

class A (x: Int) {
  …
}

fun A(y: String): A = A(y.size())

fun test() {

  val a1 = A(1)
  val a2 = A(“2”)

}


#5

I resolved it using your sugestion

public class DomainUsernamePasswordAuthenticationToken(principal: Any, credentials: String, val domain: String, authorities: Collection<GrantedAuthority>?) : UsernamePasswordAuthenticationToken(principal, credentials, authorities) {

}

fun DomainUsernamePasswordAuthenticationToken(principal: String, credentials: String, domain: String): DomainUsernamePasswordAuthenticationToken {
  return DomainUsernamePasswordAuthenticationToken(principal = principal,
           credentials = credentials,
           domain = domain,
           authorities = null)
}

fun DomainUsernamePasswordAuthenticationToken(principal: CalendarUser, credentials: String, domain: String, authorities: Collection<GrantedAuthority>): DomainUsernamePasswordAuthenticationToken {
  return DomainUsernamePasswordAuthenticationToken(principal = principal,
           credentials = credentials,
           domain = domain,
           authorities = authorities)
}


In this particular case will work, 'cause UsernamePasswordAuthenticationToken could receive a null in the authorities param, but proper secondary constructors are necesary in other cases (This could be also addressed with some type trickery)


#6

I think when authorities == null you should call setAuthenticated(false) after created instance.


#7

Isn't mandatory