TL/DR: Big script works fine for calculating on documents but throws exception when filtering
I've built a quite involved scripted field to deal with a count in a list of strings, it also dealt with parsing dates in those strings. Here it is:
int getMonth(String sigla){
if(sigla == null){
return 0;
} else if(sigla.equals("JAN")){
return 1;
} else if(sigla.equals("FEB")){
return 2;
} else if(sigla.equals("MAR")){
return 3;
} else if(sigla.equals("APR")){
return 4;
} else if(sigla.equals("MAY")){
return 5;
} else if(sigla.equals("JUN")){
return 6;
} else if(sigla.equals("JUL")){
return 7;
} else if(sigla.equals("AUG")){
return 8;
} else if(sigla.equals("SEP")){
return 9;
} else if(sigla.equals("OCT")){
return 10;
} else if(sigla.equals("NOV")){
return 11;
} else if(sigla.equals("DEC")){
return 12;
}
return 0;
}
String cleanString(String dirty){
if(dirty == null)
return '';
return dirty.toUpperCase()
.trim()
.replace('Á','A')
.replace('Ã','A')
.replace('Â','A')
.replace('É','E')
.replace('Ê','E')
.replace('Í','I')
.replace('Î','I')
.replace('Ó','O')
.replace('Ô','O')
.replace('Õ','O')
.replace('Ú','U')
.replace('Û','U')
.replace('Ç','C')
.replace('/','')
.replace('.','');
}
LocalDate getDateFromOracleString(String origin){
int dia, mes, ano;
if(origin.length() < 9)
return null;
mes = getMonth(origin.substring(3,6));
try {
dia = Integer.parseInt(origin.substring(0,2));
ano = Integer.parseInt('20'+origin.substring(7,9));
} catch(NumberFormatException e){
return null;
}
if(mes == 0 || ano < 0 || dia < 1 || dia > 31)
return null;
return LocalDate.of(ano,mes,dia);
}
boolean contLiberadas = false;
Pattern separadorTarefa = /\ \|\ /;
Pattern partesTarefa = /;/;
def tarefasString = doc['lista_tarefas.keyword'].value;
if(tarefasString == null)
return 0;
if(tarefasString.empty || tarefasString.equals(''))
return 0;
def listaTarefas = new LinkedList();
String[] tarefas = separadorTarefa.split(tarefasString);
int i;
String[] tarefaEmPartes;
for (i=0 ; i<tarefas.length ; i++){
tarefaEmPartes = partesTarefa.split(tarefas[i]);
listaTarefas.add(tarefaEmPartes);
}
def timeZone = ZoneId.of(ZoneId.SHORT_IDS.get('BET'));
LocalDate dataIniMesFechado = Instant.ofEpochMilli(new Date().getTime()).atZone(timeZone).toLocalDate().minusMonths(1).withDayOfMonth(1);
LocalDate dataFimMesFechado = Instant.ofEpochMilli(new Date().getTime()).atZone(timeZone).toLocalDate().withDayOfMonth(1).minusDays(1);
LocalDate dataRegistro;
LocalDate dataConfirmacao;
String tipoTarefa;
String ultTipoTarefa = null;
int statusTarefa;
boolean confirmada;
ListIterator l = listaTarefas.listIterator(listaTarefas.indexOf(listaTarefas.peekFirst()));
def cont = 0;
while(l.hasNext()){
tarefaEmPartes = l.next();
if(tarefaEmPartes == null)
throw new Exception('Formato de tarefa inválido - Tarefa nula na lista: ' + tarefasString);
if(tarefaEmPartes.length < 5)
throw new Exception('Formato de tarefa inválido - Tarefa: ' + tarefaEmPartes[0] + ' de tamanho inválido na lista: ' + tarefasString);
try{
statusTarefa = Integer.parseInt(tarefaEmPartes[5]);
} catch(NumberFormatException e){
if(tarefaEmPartes[5] == null)
throw new Exception('Formato de tarefa inválido - Status NULO na tarefa: ' + tarefaEmPartes[0] + ':' + tarefaEmPartes[4] + ' na lista: ' + tarefasString);
throw new Exception('Formato de tarefa inválido - Falha em interpretar o status: '+tarefaEmPartes[5] + 'na tarefa: ' + tarefaEmPartes + ' na lista: '+tarefasString);
}
if(statusTarefa != 3){
dataRegistro = getDateFromOracleString(tarefaEmPartes[0]);
if(dataRegistro == null)
throw new Exception('Formato de tarefa inválido - Falha em interpretar a data de registro: '+tarefaEmPartes[0] + 'na tarefa: ' + tarefaEmPartes + ' na lista: '+tarefasString);
if(!tarefaEmPartes[2].equals('N/A')){
confirmada = true;
dataConfirmacao = getDateFromOracleString(tarefaEmPartes[2]);
if(dataConfirmacao == null)
throw new Exception('Formato de tarefa inválido - Falha em interpretar a data de confirmação: '+tarefaEmPartes[2] + 'na tarefa: ' + tarefaEmPartes + ' na lista: '+tarefasString);
} else {
confirmada = false;
}
tipoTarefa = cleanString(tarefaEmPartes[4]);
if(tipoTarefa == '')
throw new Exception('Formato de tarefa inválido - Tipo da tarefa vazio na tarefa: '+tarefaEmPartes[0] + 'na lista: ' + tarefaEmPartes + ' na lista: '+tarefasString);
if(contLiberadas) {
if(dataRegistro.isAfter(dataIniMesFechado.minusDays(1)) && dataRegistro.isBefore(dataFimMesFechado.plusDays(1))) {
if(tipoTarefa.contains('CCC')){
if(!ultTipoTarefa.contains('CCC') && !ultTipoTarefa.contains('BBB')){
cont++;
}
} else if (tipoTarefa.contains('BBB')){
cont++;
} else if (tipoTarefa.contains('AAA')){
cont++;
}
}
}
else{
if(tipoTarefa.equals('XXX') || tipoTarefa.equals('YYY')) {
if(confirmada == true){
if(dataConfirmacao.isAfter(dataIniMesFechado.minusDays(1)) && dataConfirmacao.isBefore(dataFimMesFechado.plusDays(1))) {
cont++;
}
}
}
}
ultTipoTarefa = tipoTarefa;
}
}
return cont;
The code works fine (and yes, I know it's wonky) to calculate what it needs to calculate, but whenever I try to filter using it it throws this exception:
"type":"illegal_argument_exception","reason":"invalid sequence of tokens near ['('].","caused_by":{"type":"no_viable_alt_exception","reason":null
While pointing to this:
"type":"illegal_argument_exception","reason":"invalid sequence of tokens near ['('].","caused_by":{"type":"no_viable_alt_exception","reason":null}}}}}],"caused_by":{"type":"script_exception","reason":"compile error","script_stack":["... ou inválida
int getMonth(String sigla){
if(sigl ..."," ^---- HERE"],"script":"boolean gt(Supplier s, def v) {return s.get() > v}gt(()
I've really looked into it and I can't find what's at fault. If anyone feels like taking a look at that spaghetti and giving me a hand I'd be very thankful.