Dúvida com GroovyShell

3 respostas
Kura

Fala, galera.
Estou desenvolvendo um programinha de cadastro automático de produtos. Além de gerar todas as combinações possíveis dado os atributos do mesmo, ele calcula preço e peso através de uma fórmula.
Para ler a fórmula eu usei o shell.evaluate() da GroovyShell, mas tenho uma dúvida.
Ele faz o cálculo perfeitamente, mas quero fazer uma validação pra isso.
No código, as siglas da fórmula são substituidas de acordo com as siglas de atributos cadastrados.
A minha ideia de validação é: Caso uma ou mais siglas deixem de ser traduzidas (que significaria que o usuário digitou uma fórmula inválida para aquele produto), ao invés de dar erro ou exceção, o sistema simplesmente retorna um false qualquer.

Segue o código:

private double calculaPreco(Map<String, Object[]> mapa) {

&nbsp;formula = "(((LA/100)*(CO/100)*(ES)*PesoChapa*NP*PrecoChapa*Lucro)*3)";
&nbsp;formula += "+(0.05+0.05)*PesoChapa*1.5*(AL/100)*17*Lucro*4";
		
&nbsp;TreeMap treemap = new TreeMap(mapa);

&nbsp;Set<String> chaves = treemap.keySet();
&nbsp;&nbsp;for (String chave : chaves){
&nbsp;&nbsp;&nbsp;Object arfs[] = (Object[]) treemap.get(chave);
&nbsp;&nbsp;&nbsp;MAttribute ma = (MAttribute)arfs[0];
&nbsp;&nbsp;&nbsp;MAttributeValue mav = (MAttributeValue)arfs[1];
			
&nbsp;&nbsp;&nbsp;formula = formula.replaceAll((String)ma.get_Value("tipo"), mav.getName());
&nbsp;&nbsp;}

&nbsp;formula = formula.replaceAll("PesoChapa", "8");
&nbsp;formula = formula.replaceAll("PrecoChapa", "18");
&nbsp;formula = formula.replaceAll("Lucro", "2.8");
		
		
&nbsp;Binding binding   = new Binding();  
&nbsp;GroovyShell shell = new GroovyShell(binding);  
		   

		
&nbsp;String tancredoNeves = shell.evaluate(formula).toString();
&nbsp;double valor = Double.parseDouble(tancredoNeves);

&nbsp;return Math.ceil(valor);
}

3 Respostas

Kura

Bom… Vendo outros tópicos que teoricamente não tinham nada a ver com o meu, acabei encontrando uma solução.
Modifiquei meu método para String e depois fiz um de validação.
O método segue:

private boolean validaFormula(String formula){
	for (char c : formula.toCharArray()){
		if (Character.isLetter(c))
			return false;
	}
	return true;
}
Kura

Mas eu não tinha pensado no seguinte:
Não é só a letra na fórmula que da erro. Outras coisas também pdoem dar. um “(” a mais ou a menos, por exemplo.
Eu tentei um

private boolean validaFormula(String formula){
	Binding binding = new Binding();
	GroovyShell shell = new GroovyShell(binding);
	if (!(Boolean)shell.evaluate(formula))
		return false;
	return true;
}

Pq ficaria facil dar uma exceção por qualquer erro e, com isso, eu definir se a fórmula é ou não válida, mas não funcionou.

Alguma ideia?

Kura

Sei que não é a melhor solução, mas resolvi com try catch.

Criado 19 de fevereiro de 2009
Ultima resposta 19 de fev. de 2009
Respostas 3
Participantes 1