O código é ruim não apenas pelos números mágicos , mas porque combina vários significados no código de retorno, ocultando dentro de seu significado um erro, um aviso, uma permissão para criar uma sessão ou uma combinação dos três, o que o torna um entrada ruim para tomada de decisão.
Eu sugeriria a seguinte refatoração: retornando uma enumeração com os possíveis resultados (conforme sugerido em outras respostas), mas adicionando à enumeração um atributo indicando se é uma negação, uma renúncia (deixarei você passar desta última vez) ou se estiver OK (PASS):
public LoginResult processLogin(HttpServletRequest request, HttpServletResponse response,
int pwChangeDays, ServletContext ServContext) {
}
==> LoginResult.java <==
public enum LoginResult {
NOT_LOGGED_IN(Severity.DENIAL),
ALREADY_LOGGED_IN(Severity.PASS),
INACTIVE_USER(Severity.DENIAL),
VALID_USER(Severity.PASS),
NEEDS_PASSWORD_CHANGE(Severity.WAIVER),
INVALID_APP_USER(Severity.DENIAL),
INVALID_NETWORK_USER(Severity.DENIAL),
NON_APPROVED_ADDRESS(Severity.DENIAL),
ACCOUNT_LOCKED(Severity.DENIAL),
ACCOUNT_WILL_BE_LOCKED(Severity.WAIVER);
private Severity severity;
private LoginResult(Severity severity) {
this.severity = severity;
}
public Severity getSeverity() {
return this.severity;
}
}
==> Severity.java <==
public enum Severity {
PASS,
WAIVER,
DENIAL;
}
==> Test.java <==
public class Test {
public static void main(String[] args) {
for (LoginResult r: LoginResult.values()){
System.out.println(r + " " +r.getSeverity());
}
}
}
Saída para Test.java mostrando a gravidade de cada LoginResult:
NOT_LOGGED_IN : DENIAL
ALREADY_LOGGED_IN : PASS
INACTIVE_USER : DENIAL
VALID_USER : PASS
NEEDS_PASSWORD_CHANGE : WAIVER
INVALID_APP_USER : DENIAL
INVALID_NETWORK_USER : DENIAL
NON_APPROVED_ADDRESS : DENIAL
ACCOUNT_LOCKED : DENIAL
ACCOUNT_WILL_BE_LOCKED : WAIVER
Com base no valor da enumeração e na sua gravidade, você pode decidir se a criação da sessão continua ou não.
EDITAR:
Como resposta ao comentário de @T.Sar, alterei os possíveis valores da gravidade para PASS, WAIVER e DENIAL em vez de (OK, WARNING e ERROR). Dessa forma, fica claro que um DENIAL (anteriormente ERRO) não é um erro em si e não deve necessariamente se traduzir em gerar uma exceção. O chamador examina o objeto e decide se deve ou não lançar uma exceção, mas DENIAL é um status de resultado válido resultante da chamada processLogin(...)
.
- PASS: vá em frente, crie uma sessão se ainda não existir
- ISENÇÃO: vá em frente desta vez, mas na próxima vez que você não estiver autorizado a passar
- NEGAÇÃO: desculpe, o usuário não pode passar, não crie uma sessão