Modo de acesso a atributos (Não sei nem como perguntar)

9 respostas
L

Fala pessoal,

to precisando de uma ajuda, mas não sei nem como procurar por isso no google.
Então, qualquer idéia é bem-vinda.
O problema é o seguinte, preciso acessar atributos de objetos de uma maneira um pouco diferente da habitual.
Imaginem 3 classes: Municipio, UF e Pais
A classe Municipio tem um atributo uf do tipo UF, e esta por sua vez tem um atributo pais do tipo Pais.
Além disso, cada uma das classes tem um atributo nome.
Supondo que eu já tenha instanciado um objeto da classe Municipio, quero acessar o nome do país deste município da seguinte forma:

Municipio m = new Municipio();
//preencho aqui todo o conteúdo do objeto

System.out.println(m.uf.pais.nome);

Sei que de alguma forma o JSF faz isso ser possível, mas não faço idéia de como fazer.
Alguém dá alguma luz? Não precisa ser a solução, se derem uma dica por que assunto procurar já está ótimo.
Brigadão!

9 Respostas

F

Deixa os atributos como public

B

Leiras:
Fala pessoal,

to precisando de uma ajuda, mas não sei nem como procurar por isso no google.
Então, qualquer idéia é bem-vinda.
O problema é o seguinte, preciso acessar atributos de objetos de uma maneira um pouco diferente da habitual.
Imaginem 3 classes: Municipio, UF e Pais
A classe Municipio tem um atributo uf do tipo UF, e esta por sua vez tem um atributo pais do tipo Pais.
Além disso, cada uma das classes tem um atributo nome.
Supondo que eu já tenha instanciado um objeto da classe Municipio, quero acessar o nome do país deste município da seguinte forma:

Municipio m = new Municipio();
//preencho aqui todo o conteúdo do objeto

System.out.println(m.uf.pais.nome);

Sei que de alguma forma o JSF faz isso ser possível, mas não faço idéia de como fazer.
Alguém dá alguma luz? Não precisa ser a solução, se derem uma dica por que assunto procurar já está ótimo.
Brigadão!

Ola,

O JSF não, quem faz isto é uma linguagem chamada EL, que está imbutido na maioria dos containers… e é desenvida pela sun para facilitar a vida web…

Agora, acessar este atributos, diretamente, seria só deixa-los publicos… mas isto seria uma violação ao conceito de encapsulamento de OO… vale a pena???

A um padrão chamado delegator, que resolveria o caso…

L

Putz, eu realmente não gostaria de deixar os atributos públicos.
A estrutura do sistema está tão “bonita”, que dá dó de apelar pra essa solução, hehe.
Mas, se a EL faz isso, será que eu não consigo usar algo já pronto dela?
Ou mesmo reimplementar (copiar) a solução?

B

Leiras:
Putz, eu realmente não gostaria de deixar os atributos públicos.
A estrutura do sistema está tão “bonita”, que dá dó de apelar pra essa solução, hehe.
Mas, se a EL faz isso, será que eu não consigo usar algo já pronto dela?
Ou mesmo reimplementar (copiar) a solução?

Pelo que entendi nos meus estudos sobre EL, ele pega o que vc colocou ${cidade.uf.pais.nome} e transforma no que vc realmente está querendo… cidade.getUf().getPais().getNome() tanto que para usar EL vc tem que seguir o padrão bean…

B

Documentação de EL:
http://java.sun.com/products/jsp/reference/techart/unifiedEL.html

J

Isso é um sistema web? Se sim, é só usar EL mesmo, como já foi passado… de toda forma você vai precisar de métodos get, para web use EL para chamá-los, se não for web, simplesmente chame os métodos diretamente:

System.out.println(m.getUf().getPais().getNome());
L

Fala pessoal,

acabei optando por uma solução "caseira".
Estou postando o código caso alguém precise de algo parecido.
Abraço, e obrigado pela ajuda!

public class Main {

	public static void main(String[] args) {
		Pais p = new Pais();
		p.setNome("Brasil");
		
		UF uf = new UF();
		uf.setPais(p);
		uf.setSigla("SP");
		
		Municipio m = new Municipio();
		m.setUf(uf);
		m.setNome("Santo André");
		
		try {
			System.out.println(Main.getValue(m, "uf.pais.nome"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static String getValue(Object object, String expression) throws Exception {
		String value = null;		
		String[] attributes = expression.split("\\."); 
		
		if (attributes.length > 1) {
			Method m = object.getClass().getDeclaredMethod(Main.getMethodName(attributes[0]));
			return Main.getValue(m.invoke(object), Main.getNewExpression(expression));				
			
		} else {						
			Method m = object.getClass().getDeclaredMethod(Main.getMethodName(attributes[0]));			
			value = (String)m.invoke(object);			
		}		
		
		return value;
	}	
	
	public static String getMethodName(String attribute) {
		String methodName = null;		
		if (attribute != null) {
			methodName = "get"+attribute.substring(0, 1).toUpperCase()+attribute.substring(1, attribute.length());			
		}				
		return methodName;
	}
	
	public static String getNewExpression(String expression) {
		String newExpression = "";		
		if (expression != null) {
			newExpression = "";
			String[] attributes = expression.split("\\.");
			
			for (int i=1, iLen=attributes.length; i<iLen; i++) {
				newExpression += attributes[i]+".";
			}
			newExpression = newExpression.substring(0, newExpression.length()-1);		
		} 		
		return newExpression;		
	}

}
>
J

Só não entendi o objetivo de se usar reflection em algo assim… :???:

L

Fala Jair,

É q eu to trabalhando num sistema desenvolvido em JSF, e queria fazer um método genérico de exportação de tabelas (HtmlDataTable) para pdf, excel, etc.
Atualmente passo um model para um método, que gera as tabelas.
Neste model, o conteúdo de cada coluna é definido no modo da EL (uf.pais.nome).
Como eu queria utilizar o mesmo model para a geração dos documentos, tive que usar o reflection junto com a EL para obter o resultado q eu queria.

Criado 12 de março de 2009
Ultima resposta 16 de mar. de 2009
Respostas 9
Participantes 4