[RESOLVIDO] Problemas ao executar código após instanciar uma Component SessionScoped no VRaptor

Estou usando Ubuntu 11.10, OpenJDK 6 instalado, Tomcat 7, Eclipse Indigo e Vraptor-3.4.0.

Estou tentando adicionar uma String numa variável de uma Component SessionScoped a partir de outra classe, então criei outra Component Session Scoped que recebe o primeiro Component e tenta adicionar essa String.

Gostaria de saber se isso é possível e se for, o que eu estou fazendo de errado, pois não estou conseguindo adicionar essa String.

Agradeço quem ajudar, ou tentar ajudar :smiley:

Primeiro Component SessionScoped, é uma classe que herda ArrayList:
Obs.: Eu preciso que essa classe funcione exatamente como uma List, por isso dei extend no ArrayList.

[code]@Component
@SessionScoped
public class UserRoles extends ArrayList {

private static final long serialVersionUID = 8587520375423685556L;

}[/code]

Segundo Component SessionScoped, quero usar essa classe para adicionar um valor no UserRoles:

[code]@Component
@SessionScoped
public class UserRolesInitialSetter {
private final UserRoles userRoles;

public UserRolesInitialSetter(UserRoles userRoles) {
	this.userRoles = userRoles;
	this.userRoles.add("NotAuthenticatedUser");
}

}[/code]

Também tentei usar @PostConstruct, mas não funcionou:

[code]@Component
@SessionScoped
public class UserRolesInitialSetter {
private final UserRoles userRoles;

public UserRolesInitialSetter(UserRoles userRoles) {
	this.userRoles = userRoles;
}

@PostConstruct
public void setDefaultUserRole(){
	this.userRoles.add("NotAuthenticatedUser");
}

}[/code]

você está usando a UserRolesInitialSetter em algum lugar? se não, ela não vai ser criada, então o setDefaultUserRole() não vai ser chamado…

pq vc não coloca esse método na própria UserRoles?

PS: algum motivo especial pra UserRoles estender ArrayList ao invés de ter um atributo que é uma arrayList?

[quote=Lucas Cavalcanti]você está usando a UserRolesInitialSetter em algum lugar? se não, ela não vai ser criada, então o setDefaultUserRole() não vai ser chamado…

pq vc não coloca esse método na própria UserRoles?

PS: algum motivo especial pra UserRoles estender ArrayList ao invés de ter um atributo que é uma arrayList?[/quote]

Entendi. Eu tinha pensado que ao anotar com @SessionScoped, um objeto daquela classe seria instanciado ao criar uma sessão para o usuário.

Sobre o motivo de estender o ArrayList era só para não precisar ficar chamando userRoles.getList().add(), e só chamar userRoles.add(). Mas eu vou colocar como atributo mesmo, pois vou dar a opção de setar a própria list.

Obrigado pela resposta.

Quero perguntar só mais uma coisa. É possível executar um código assim que a HttpSession do usuário é iniciada? Sendo que eu vou precisar do userRoles da sessão do usuário

se for de um componente específico, só anotar um método com @PreDestroy.

se for algo geral do sistema, vc pode registrar um listener no web.xml

[quote=Lucas Cavalcanti]se for de um componente específico, só anotar um método com @PreDestroy.

se for algo geral do sistema, vc pode registrar um listener no web.xml[/quote]

Não entendi a parte de anotar um método com o @PreDestroy.

Usar listener vai ficar muito complicado. Quero fazer uma coisa simples, usando as opções do VRaptor, sem usar HttpSession, HttpServlet, etc.

Tô pensando em criar uma inteface InitialUserRolesProvider (Talvez não use esse nome), e pedir para quem for usar o código implementar minha interface, anotar com component e denifir um customProvider como é ensinado em http://vraptor.caelum.com.br/documentacao/injecao-de-dependencias/, registrando a classe implementadora para a minha interface. Mas mesmo assim ficou complicado.

o do pre-destroy é assim:

@Component  
@SessionScoped  
public class UserRolesInitialSetter {  
    private final UserRoles userRoles;  
  
    public UserRolesInitialSetter(UserRoles userRoles) {  
        this.userRoles = userRoles;  
        this.userRoles.add("NotAuthenticatedUser");  
    }  

    @PreDestroy
    public void fazAlgo() {
        // isso será executado ao fim da sessão do usuário
    }
}  

[quote=Lucas Cavalcanti]o do pre-destroy é assim:

@Component  
@SessionScoped  
public class UserRolesInitialSetter {  
    private final UserRoles userRoles;  
  
    public UserRolesInitialSetter(UserRoles userRoles) {  
        this.userRoles = userRoles;  
        this.userRoles.add("NotAuthenticatedUser");  
    }  

    @PreDestroy
    public void fazAlgo() {
        // isso será executado ao fim da sessão do usuário
    }
}  
[/code][/quote]

Entendi. Só que eu queria executar no início da Sessão.

Minha solução foi a seguinte:

Crio uma interface que deve ser implementada por quem quiser setar valores padrões
[code]public interface EAccessCon4VraptorInitialDefaultValueProvider {

	public List<String> getRoles();

	public List<Method> getMethodDenials();

	public List<Method> getMethodPermissions();

	public List<Class<?>> getResourceDenials();

	public List<Class<?>> getResourcePermissions();

}[/code]

Programador implementa minha interface
[code]@Component
public class EAccessConDefaultValueProvider implements
		EAccessCon4VraptorInitialDefaultValueProvider {

	@Override
	public List<String> getRoles() {
		List<String> roles = new ArrayList<String>();
		roles.add("NotAuthenticatedUser");
		return roles;
	}

	@Override
	public List<Method> getMethodDenials() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Method> getMethodPermissions() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Class<?>> getResourceDenials() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Class<?>> getResourcePermissions() {
		// TODO Auto-generated method stub
		return null;
	}

Criar um customProvider e registrar a classe para minha interface

[code]public class CustomProvider extends SpringProvider {

@Override
protected void registerCustomComponents(ComponentRegistry registry) {
	registry.register(EAccessCon4VraptorInitialDefaultValueProvider.class,
			EAccessConDefaultValueProvider.class);
}

}[/code]

Definir o CustomProvider no context-param

<context-param> <param-name>br.com.caelum.vraptor.provider</param-name> <param-value>(Caminho para o CustomProvider)</param-value> </context-param>

Então uso a classe que define os valores padrões por meio da minha interface. Aí o código do programador que me permite pegar os valores padrões vai ser executado no início da sessão do usuário, já que eu vou fazer uma chamada direta para os métodos.

@Component
@SessionScoped
public class UserAccessDefinitions {
	private List<Method> methodDenials;
	private List<Method> methodPermissions;
	private List<Class<?>> resourceDenials;
	private List<Class<?>> resourcePermissions;
	private List<String> roles;

	private EAccessCon4VraptorInitialDefaultValueProvider defaultValuesProvider;

	public UserAccessDefinitions(
			EAccessCon4VraptorInitialDefaultValueProvider defaultValuesProvider) {
		this.defaultValuesProvider = defaultValuesProvider;
	}

	@PostConstruct
	public void addDefaultValues() {
        //Inicio as variáveis aqui, usando o defaultValuesProvider. Seria melhor iniciar no construtor?
	}

    // setters e getters
}

Por enquanto essa é minha solução. Ficou um pouco complicado, hehehe.

se é um @Component, vc não precisa do custom provider, pode tirá-lo…

qto a usar o @PostConstruct ou o construtor, é meio equivalente… talvez seja melhor fazer no construtor mesmo.

[quote=Lucas Cavalcanti]se é um @Component, vc não precisa do custom provider, pode tirá-lo…

qto a usar o @PostConstruct ou o construtor, é meio equivalente… talvez seja melhor fazer no construtor mesmo.[/quote]

A classe é um component, mas eu vou usar a interface, então acho que precisa do CustomProvider.

não precisa, o VRaptor consegue se virar :wink:

Eu estava usando o CustomProvider, tinha pensado que quando usava interface tinha que usar. Depois que você falou que o VRaptor gerencia isso, eu fui ver minhas classes. Estava dando erro porque tinha umas classes que faltavam o @Component e eu achava que elas já estavam anotadas. Huahuahuahuahauha.

Pow, ajudou muito.