/**
*
*/
package net.conselldemallorca.helium.core.model.dao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.springframework.stereotype.Component;
import org.springmodules.lucene.search.core.HitExtractor;
import net.conselldemallorca.helium.core.helperv26.LuceneHelper;
import net.conselldemallorca.helium.core.model.dto.DadaIndexadaDto;
import net.conselldemallorca.helium.core.model.hibernate.Camp;
import net.conselldemallorca.helium.core.model.hibernate.Camp.TipusCamp;
import net.conselldemallorca.helium.core.model.hibernate.Entorn;
import net.conselldemallorca.helium.core.model.hibernate.Expedient;
import net.conselldemallorca.helium.core.model.hibernate.ExpedientTipus;
import net.conselldemallorca.helium.core.util.ExpedientCamps;
/**
* Dao per a indexar i consultar expedients emprant lucene
*
* @author Limit Tecnologies <limit@limit.es>
*/
@Component
public class LuceneDao extends LuceneHelper {
public List<Map<String, DadaIndexadaDto>> getDadesExpedient(
Entorn entorn,
Expedient expedient,
List<Camp> informeCamps) {
mesuresTemporalsHelper.mesuraIniciar("Lucene: getDadesExpedient", "lucene", expedient.getTipus().getNom());
checkIndexOk();
Query query = queryFromCampFiltre(
ExpedientCamps.EXPEDIENT_CAMP_ID,
expedient.getId().toString(),
null);
List<Map<String, DadaIndexadaDto>> resultat = getDadesExpedientPerConsulta(entorn, query, informeCamps, false, ExpedientCamps.EXPEDIENT_CAMP_ID, true, 0, -1);
mesuresTemporalsHelper.mesuraCalcular("Lucene: getDadesExpedient", "lucene", expedient.getTipus().getNom());
return resultat;
}
public List<Map<String, DadaIndexadaDto>> findAmbDadesExpedient(
Entorn entorn,
ExpedientTipus expedientTipus,
List<Camp> filtreCamps,
Map<String, Object> filtreValors,
List<Camp> informeCamps,
String sort,
boolean asc,
int firstRow,
int maxResults) {
mesuresTemporalsHelper.mesuraIniciar("Lucene: findAmbDadesExpedient", "lucene");
checkIndexOk();
Query query = getLuceneQuery(
entorn,
expedientTipus,
filtreCamps,
filtreValors);
List<Map<String, DadaIndexadaDto>> resultat = getDadesExpedientPerConsulta(
entorn, query, informeCamps, true, sort, asc, firstRow, maxResults);
mesuresTemporalsHelper.mesuraCalcular("Lucene: findAmbDadesExpedient", "lucene");
return resultat;
}
public List<Map<String, DadaIndexadaDto>> findAmbDadesExpedient(
Entorn entorn,
ExpedientTipus expedientTipus,
List<Camp> filtreCamps,
Map<String, Object> filtreValors,
List<Camp> informeCamps,
String sort,
boolean asc,
int firstRow,
int maxResults,
List<Long> ids) {
mesuresTemporalsHelper.mesuraIniciar("Lucene: findAmbDadesExpedient", "lucene");
checkIndexOk();
Query query = null;
if (ids != null && !ids.isEmpty()) {
query = getLuceneQuery(entorn, expedientTipus, filtreCamps, filtreValors, ids.subList(1, ids.size()));
} else {
query = getLuceneQuery(entorn, expedientTipus, filtreCamps, filtreValors);
}
List<Map<String, DadaIndexadaDto>> resultat = getDadesExpedientPerConsulta(
entorn,
query,
informeCamps,
true,
sort,
asc,
firstRow,
maxResults);
mesuresTemporalsHelper.mesuraCalcular("Lucene: findAmbDadesExpedient", "lucene");
return resultat;
}
@SuppressWarnings("unchecked")
private List<Map<String, DadaIndexadaDto>> getDadesExpedientPerConsulta(
final Entorn entorn,
Query query,
List<Camp> campsInforme,
boolean incloureId,
String sort,
boolean asc,
final int firstRow,
final int maxResults) {
Sort luceneSort = null;
if (sort != null && sort.length() > 0) {
if (ExpedientCamps.EXPEDIENT_CAMP_TITOL.equals(sort)) {
sort = sort + "_no_analyzed";
} else if (ExpedientCamps.EXPEDIENT_CAMP_NUMERO.equals(sort)) {
sort = sort + "_no_analyzed";
} else if (ExpedientCamps.EXPEDIENT_CAMP_COMENTARI.equals(sort)) {
sort = sort + "_no_analyzed";
} else {
for (Camp camp : campsInforme) {
if (sort.endsWith(camp.getCodi()) && (camp.getTipus().equals(TipusCamp.STRING) || camp.getTipus().equals(TipusCamp.TEXTAREA))) {
sort = sort + "_no_analyzed";
break;
}
}
String campOrdenacio = null;
if ("expedient$identificador".equals(sort)) {
campOrdenacio = ExpedientCamps.EXPEDIENT_CAMP_ID;
} else {
campOrdenacio = sort;
}
luceneSort = new Sort(new SortField(campOrdenacio, SortField.STRING, !asc));
}
} else
luceneSort = new Sort(new SortField(ExpedientCamps.EXPEDIENT_CAMP_ID, SortField.STRING, !asc));
final List<Map<String, List<String>>> resultats = searchTemplate.search(query, new HitExtractor() {
private int count = 0;
public Object mapHit(int id, Document document, float score) {
Map<String, List<String>> valorsDocument = null;
boolean ignorar = false;
if (PEGAT_ENTORN_ACTIU) {
Field campEntorn = document.getField(ExpedientCamps.EXPEDIENT_CAMP_ENTORN);
ignorar = campEntorn != null && !campEntorn.stringValue().equals(entorn.getCodi());
}
if (!ignorar) {
if (maxResults == -1 || (count >= firstRow && count < firstRow + maxResults)) {
valorsDocument = new HashMap<String, List<String>>();
for (Field field : (List<Field>) document.getFields()) {
if (valorsDocument.get(field.name()) == null) {
List<String> valors = new ArrayList<String>();
valors.add(field.stringValue());
valorsDocument.put(field.name(), valors);
} else {
List<String> valors = valorsDocument.get(field.name());
valors.add(field.stringValue());
}
}
}
count++;
}
return valorsDocument;
}
}, luceneSort);
List<Map<String, DadaIndexadaDto>> resposta = new ArrayList<Map<String, DadaIndexadaDto>>();
if (resultats.size() > 0) {
Set<String> clausAmbValorMultiple = new HashSet<String>();
for (Map<String, List<String>> fila : resultats) {
if (fila != null) {
List<DadaIndexadaDto> dadesFila = new ArrayList<DadaIndexadaDto>();
for (String codi : fila.keySet()) {
for (Camp camp : campsInforme) {
boolean coincideix;
String[] partsCodi = codi.split("\\.");
if (codi.startsWith(ExpedientCamps.EXPEDIENT_PREFIX)) {
coincideix = codi.equals(camp.getCodi());
} else {
coincideix = camp.getDefinicioProces() != null && partsCodi[0].equals(camp.getDefinicioProces().getJbpmKey()) && partsCodi[1].equals(camp.getCodi());
}
if (coincideix) {
for (String valorIndex : fila.get(codi)) {
try {
Object valor = valorCampPerIndex(camp, valorIndex);
if (valor != null) {
DadaIndexadaDto dadaCamp;
if (codi.startsWith(ExpedientCamps.EXPEDIENT_PREFIX)) {
dadaCamp = new DadaIndexadaDto(camp.getCodi(), camp.getEtiqueta());
} else {
dadaCamp = new DadaIndexadaDto(partsCodi[0], partsCodi[1], camp.getEtiqueta());
}
if (camp.getTipus().equals(TipusCamp.SELECCIO) || camp.getTipus().equals(TipusCamp.SUGGEST))
dadaCamp.setOrdenarPerValorMostrar(true);
dadaCamp.setMultiple(false);
dadaCamp.setValorIndex(valorIndex);
dadaCamp.setValor(valor);
String textDomini = null;
List<String> textDominiIndex = fila.get(codi + VALOR_DOMINI_SUFIX + valor);
if (textDominiIndex != null)
textDomini = textDominiIndex.get(0);
if (textDomini == null)
textDomini = (valor != null && valor.toString().length() > 0) ? "¿" + valor.toString() + "?" : null;
dadaCamp.setValorMostrar(Camp.getComText(camp.getTipus(), valor, textDomini));
dadesFila.add(dadaCamp);
}
} catch (Exception ex) {
logger.error("Error al obtenir el valor de l'índex pel camp " + codi, ex);
}
}
break;
}
}
}
Map<String, DadaIndexadaDto> mapFila = new HashMap<String, DadaIndexadaDto>();
if (incloureId) {
/* Incorpora l'id de l'expedient */
DadaIndexadaDto dadaExpedientId = new DadaIndexadaDto(ExpedientCamps.EXPEDIENT_CAMP_ID, "expedientId");
dadaExpedientId.setValorIndex(fila.get(ExpedientCamps.EXPEDIENT_CAMP_ID).get(0));
mapFila.put(CLAU_EXPEDIENT_ID, dadaExpedientId);
}
for (DadaIndexadaDto dada : dadesFila) {
if (mapFila.containsKey(dada.getReportFieldName())) {
DadaIndexadaDto dadaMultiple = mapFila.get(dada.getReportFieldName());
if (!dadaMultiple.isMultiple()) {
clausAmbValorMultiple.add(dada.getReportFieldName());
dadaMultiple.addValorMultiple(dadaMultiple.getValor());
dadaMultiple.addValorIndexMultiple(dadaMultiple.getValorIndex());
dadaMultiple.addValorMostrarMultiple(dadaMultiple.getValorMostrar());
dadaMultiple.setValor(null);
dadaMultiple.setValorIndex(null);
dadaMultiple.setValorMostrar(null);
dadaMultiple.setMultiple(true);
}
dadaMultiple.addValorMultiple(dada.getValor());
dadaMultiple.addValorIndexMultiple(dada.getValorIndex());
dadaMultiple.addValorMostrarMultiple(dada.getValorMostrar());
} else {
mapFila.put(dada.getReportFieldName(), dada);
}
}
resposta.add(mapFila);
}
}
// Revisa les variables de tipus registre que només
// ténen 1 fila per a marcar-les com a múltiples
for (Map<String, DadaIndexadaDto> dadesExpedient : resposta) {
for (String clauMultiple : clausAmbValorMultiple) {
DadaIndexadaDto dadaMultiple = dadesExpedient.get(clauMultiple);
if (dadaMultiple != null && !dadaMultiple.isMultiple()) {
dadaMultiple.addValorMultiple(dadaMultiple.getValor());
dadaMultiple.addValorIndexMultiple(dadaMultiple.getValorIndex());
dadaMultiple.addValorMostrarMultiple(dadaMultiple.getValorMostrar());
dadaMultiple.setValor(null);
dadaMultiple.setValorIndex(null);
dadaMultiple.setValorMostrar(null);
dadaMultiple.setMultiple(true);
}
}
}
}
return resposta;
}
}