/** * */ package net.conselldemallorca.helium.webapp.v3.helper; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import net.conselldemallorca.helium.v3.core.api.dto.PaginaDto; import net.conselldemallorca.helium.v3.core.api.dto.PaginacioParamsDto; import net.conselldemallorca.helium.v3.core.api.dto.PaginacioParamsDto.OrdreDireccioDto; import net.conselldemallorca.helium.webapp.v3.helper.AjaxHelper.AjaxFormResponse; /** * Mètodes d'ajuda per a gestionar datatables. * * @author Limit Tecnologies <limit@limit.es> */ public class DatatablesHelper { private static final String ATRIBUT_ROW_ID = "DT_RowId"; //private static final String ATRIBUT_ROW_DATA = "DT_RowData"; private static final String ATRIBUT_ID = "DT_Id"; public static PaginacioParamsDto getPaginacioDtoFromRequest( HttpServletRequest request) { return getPaginacioDtoFromRequest(request, null, null); } private static PaginacioParamsDto getPaginacioDtoFromRequest( HttpServletRequest request, Map<String, String[]> mapeigFiltres, Map<String, String[]> mapeigOrdenacions) { DatatablesParams params = new DatatablesParams(request); LOGGER.debug("Informació de la pàgina obtingudes de datatables (" + "draw=" + params.getDraw() + ", " + "start=" + params.getStart() + ", " + "length=" + params.getLength() + ")"); PaginacioParamsDto paginacio = new PaginacioParamsDto(); int paginaNum = params.getStart() / params.getLength(); paginacio.setPaginaNum(paginaNum); if (params.getLength() != null && params.getLength().intValue() == -1) { paginacio.setPaginaTamany(Integer.MAX_VALUE); } else { paginacio.setPaginaTamany(params.getLength()); } paginacio.setFiltre(params.getSearchValue()); for (int i = 0; i < params.getColumnsSearchValue().size(); i++) { String columna = params.getColumnsData().get(i); String[] columnes = new String[] {columna}; if (mapeigFiltres != null && mapeigFiltres.get(columna) != null) { columnes = mapeigFiltres.get(columna); } for (String col: columnes) { if (!"<null>".equals(col)) { paginacio.afegirFiltre( col, params.getColumnsSearchValue().get(i)); LOGGER.debug("Afegit filtre a la paginació (" + "columna=" + col + ", " + "valor=" + params.getColumnsSearchValue().get(i) + ")"); } } } for (int i = 0; i < params.getOrderColumn().size(); i++) { int columnIndex = params.getOrderColumn().get(i); String columna = params.getColumnsData().get(columnIndex); OrdreDireccioDto direccio; if ("asc".equals(params.getOrderDir().get(i))) direccio = OrdreDireccioDto.ASCENDENT; else direccio = OrdreDireccioDto.DESCENDENT; String[] columnes = new String[] {columna}; if (mapeigOrdenacions != null && mapeigOrdenacions.get(columna) != null) { columnes = mapeigOrdenacions.get(columna); } for (String col: columnes) { paginacio.afegirOrdre(col, direccio); LOGGER.debug("Afegida ordenació a la paginació (columna=" + columna + ", direccio=" + direccio + ")"); } } LOGGER.debug("Informació de la pàgina sol·licitada (paginaNum=" + paginacio.getPaginaNum() + ", paginaTamany=" + paginacio.getPaginaTamany() + ")"); return paginacio; } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, PaginaDto<T> pagina) { return getDatatableResponse(request, null, pagina, null); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, PaginaDto<T> pagina, String atributId) { return getDatatableResponse(request, null, pagina, atributId); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, PaginaDto<T> pagina) { return getDatatableResponse(request, bindingResult, pagina, null); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, PaginaDto<T> pagina, String atributId) { LOGGER.debug("Generant informació de resposta per datatable (" + "numero=" + pagina.getNumero() + ", " + "tamany=" + pagina.getTamany() + ", " + "total=" + pagina.getTotal() + ", " + "elementsTotal=" + pagina.getElementsTotal() + ")"); if (bindingResult != null && bindingResult.hasErrors()) { DatatablesResponse emptyResponse = getDatatableResponse(request, null, (List<T>)null, null); emptyResponse.setFiltreFormResponse( AjaxHelper.generarAjaxFormErrors(null, bindingResult)); return emptyResponse; } DatatablesParams params = new DatatablesParams(request); DatatablesResponse response = new DatatablesResponse(); response.setDraw((params.getDraw() != null) ? params.getDraw().intValue() : 0); response.setRecordsFiltered(pagina.getElementsTotal()); response.setRecordsTotal(pagina.getElementsTotal()); List<Map<String, Object>> dataMap = new ArrayList<Map<String, Object>>(); if (pagina.getContingut() != null) { int index = 0; for (T registre: pagina.getContingut()) { List<PropertyDescriptor> descriptors = getBeanPropertyDescriptors(registre); Object[] dadesRegistre = new Object[params.getColumnsData().size()]; Map<String, Object> mapRegistre = new HashMap<String, Object>(); for (int i = 0; i < params.getColumnsData().size(); i++) { String propietatNom = params.getColumnsData().get(i); try { if (propietatNom.contains(".")) { propietatNom = propietatNom.substring(0, propietatNom.indexOf(".")); } Object valor = getPropietatValor(registre, propietatNom, descriptors); /*if (valor instanceof Enum) { // Tractament de l'enumerat valor = MessageHelper.getInstance().getMessage( "enum." + valor.getClass().getSimpleName() + "." + valor.toString(), null, new RequestContext(request).getLocale()); }*/ mapRegistre.put( propietatNom, valor); dadesRegistre[i] = valor; } catch (Exception ex) { dadesRegistre[i] = "(!)"; LOGGER.error( "No s'ha pogut llegir la propietat de l'objecte (" + "propietatNom=" + propietatNom + ")", ex); } } if (atributId != null) { try { Object valor = getPropietatValor(registre, atributId, descriptors); mapRegistre.put( ATRIBUT_ROW_ID, "row_" + valor); mapRegistre.put( ATRIBUT_ID, valor); } catch (Exception ex) { LOGGER.error( "No s'ha pogut llegir la propietat de l'objecte (" + "propietatNom=" + atributId + ")", ex); } /*mapRegistre.put( ATRIBUT_ROW_DATA, getRowData( registre, atributId));*/ } else { mapRegistre.put( ATRIBUT_ROW_ID, "row_" + index); mapRegistre.put( ATRIBUT_ID, index); } dataMap.add(mapRegistre); index++; } } response.setData(dataMap); LOGGER.debug("Informació per a datatables (" + "draw=" + response.getDraw() + "," + "recordsFiltered=" + response.getRecordsFiltered() + "," + "recordsTotal=" + response.getRecordsTotal() + ")"); return response; } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, List<T> llista) { return getDatatableResponse(request, bindingResult, llista, null); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, List<T> llista, String atributId) { if (llista != null) LOGGER.debug("Informació de la llista (tamany=" + llista.size() + ")"); else LOGGER.debug("Informació de la llista (null)"); PaginaDto<T> dto = new PaginaDto<T>(); dto.setNumero(0); dto.setTamany((llista != null) ? llista.size() : 0); dto.setTotal(1); dto.setElementsTotal((llista != null) ? llista.size() : 0); dto.setAnteriors(false); dto.setPrimera(true); dto.setPosteriors(false); dto.setDarrera(true); dto.setContingut(llista); return getDatatableResponse(request, bindingResult, dto, atributId); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, T element) { return getDatatableResponse(request, null, element, null); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, T element, String atributId) { return getDatatableResponse(request, null, element, atributId); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, T element) { return getDatatableResponse(request, bindingResult, element, null); } public static <T> DatatablesResponse getDatatableResponse( HttpServletRequest request, BindingResult bindingResult, T element, String atributId) { List<T> list = new ArrayList<T>(); list.add(element); return getDatatableResponse(request, bindingResult, list, atributId); } public static <T> DatatablesResponse getEmptyDatatableResponse( HttpServletRequest request) { return getDatatableResponse(request, null, (List<T>)null, null); } public static <T> DatatablesResponse getEmptyDatatableResponse( HttpServletRequest request, BindingResult bindingResult) { return getDatatableResponse(request, bindingResult, (List<T>)null, null); } public static class DatatablesResponse { private int draw; private long recordsTotal; private long recordsFiltered; private List<Map<String, Object>> data; private String error; private AjaxFormResponse filtreFormResponse; public DatatablesResponse() { } public int getDraw() { return draw; } public void setDraw(int draw) { this.draw = draw; } public long getRecordsTotal() { return recordsTotal; } public void setRecordsTotal(long recordsTotal) { this.recordsTotal = recordsTotal; } public long getRecordsFiltered() { return recordsFiltered; } public void setRecordsFiltered(long recordsFiltered) { this.recordsFiltered = recordsFiltered; } public List<Map<String, Object>> getData() { return data; } public void setData(List<Map<String, Object>> data) { this.data = data; } public String getError() { return error; } public void setError(String error) { this.error = error; } public AjaxFormResponse getFiltreFormResponse() { return filtreFormResponse; } public void setFiltreFormResponse(AjaxFormResponse filtreFormResponse) { this.filtreFormResponse = filtreFormResponse; } public boolean isFiltreError() { return filtreFormResponse != null; } } public static class DatatablesParams { private Integer draw; private Integer start; private Integer length; private String searchValue; private Boolean searchRegex; private List<Integer> orderColumn = new ArrayList<Integer>(); private List<String> orderDir = new ArrayList<String>(); private List<String> columnsData = new ArrayList<String>(); private List<String> columnsName = new ArrayList<String>(); private List<Boolean> columnsSearchable = new ArrayList<Boolean>(); private List<Boolean> columnsOrderable = new ArrayList<Boolean>(); private List<String> columnsSearchValue = new ArrayList<String>(); private List<Boolean> columnsSearchRegex = new ArrayList<Boolean>(); public DatatablesParams(HttpServletRequest request) { if (request.getParameter("draw") != null) draw = Integer.parseInt(request.getParameter("draw")); if (request.getParameter("start") != null) start = Integer.parseInt(request.getParameter("start")); if (request.getParameter("length") != null) length = Integer.parseInt(request.getParameter("length")); if (request.getParameter("search[value]") != null) searchValue = request.getParameter("search[value]"); if (request.getParameter("search[regex]") != null) searchRegex = Boolean.parseBoolean(request.getParameter("search[regex]")); for (int i = 0;; i++) { String paramPrefix = "order[" + i + "]"; if (request.getParameter(paramPrefix + "[column]") != null) { orderColumn.add(Integer.parseInt(request.getParameter(paramPrefix + "[column]"))); orderDir.add(request.getParameter(paramPrefix + "[dir]")); } else { break; } } for (int i = 0;; i++) { String paramPrefix = "columns[" + i + "]"; if (request.getParameter(paramPrefix + "[data]") != null) { columnsData.add(request.getParameter(paramPrefix + "[data]")); columnsName.add(request.getParameter(paramPrefix + "[name]")); columnsSearchable.add(Boolean.parseBoolean(request.getParameter(paramPrefix + "[searchable]"))); columnsOrderable.add(Boolean.parseBoolean(request.getParameter(paramPrefix + "[orderable]"))); columnsSearchValue.add(request.getParameter(paramPrefix + "[search][value]")); columnsSearchRegex.add(Boolean.parseBoolean(request.getParameter(paramPrefix + "[search][regex]"))); } else { break; } } } public Integer getDraw() { return draw; } public void setDraw(Integer draw) { this.draw = draw; } public Integer getStart() { return start; } public void setStart(Integer start) { this.start = start; } public Integer getLength() { return length; } public void setLength(Integer length) { this.length = length; } public String getSearchValue() { return searchValue; } public void setSearchValue(String searchValue) { this.searchValue = searchValue; } public Boolean getSearchRegex() { return searchRegex; } public void setSearchRegex(Boolean searchRegex) { this.searchRegex = searchRegex; } public List<Integer> getOrderColumn() { return orderColumn; } public void setOrderColumn(List<Integer> orderColumn) { this.orderColumn = orderColumn; } public List<String> getOrderDir() { return orderDir; } public void setOrderDir(List<String> orderDir) { this.orderDir = orderDir; } public List<String> getColumnsData() { return columnsData; } public void setColumnsData(List<String> columnsData) { this.columnsData = columnsData; } public List<String> getColumnsName() { return columnsName; } public void setColumnsName(List<String> columnsName) { this.columnsName = columnsName; } public List<Boolean> getColumnsSearchable() { return columnsSearchable; } public void setColumnsSearchable(List<Boolean> columnsSearchable) { this.columnsSearchable = columnsSearchable; } public List<Boolean> getColumnsOrderable() { return columnsOrderable; } public void setColumnsOrderable(List<Boolean> columnsOrderable) { this.columnsOrderable = columnsOrderable; } public List<String> getColumnsSearchValue() { return columnsSearchValue; } public void setColumnsSearchValue(List<String> columnsSearchValue) { this.columnsSearchValue = columnsSearchValue; } public List<Boolean> getColumnsSearchRegex() { return columnsSearchRegex; } public void setColumnsSearchRegex(List<Boolean> columnsSearchRegex) { this.columnsSearchRegex = columnsSearchRegex; } } private static List<PropertyDescriptor> getBeanPropertyDescriptors( Object bean) { List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>( Arrays.asList( PropertyUtils.getPropertyDescriptors(bean))); Iterator<PropertyDescriptor> it = descriptors.iterator(); while (it.hasNext()) { PropertyDescriptor pd = it.next(); if ("class".equals(pd.getName())) { it.remove(); break; } } return descriptors; } /*private static Map<String, Object> getRowData( Object bean, String atributId) { Map<String, Object> rowData = new HashMap<String, Object>(); try { rowData.put( "id", PropertyUtils.getProperty(bean, atributId)); } catch (Exception ex) { LOGGER.error( "No s'ha pogut llegir la propietat de l'objecte (" + "propietatNom=" + atributId + ")", ex); } return rowData; }*/ private static Object getPropietatValor( Object registre, String propietatNom, List<PropertyDescriptor> descriptors) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Object valor = null; try { int index = Integer.parseInt(propietatNom); valor = PropertyUtils.getProperty(registre, descriptors.get(index).getName()); } catch (NumberFormatException ex) { if (propietatNom != null && !propietatNom.isEmpty() && !"<null>".equals(propietatNom)) { valor = PropertyUtils.getProperty(registre, propietatNom); } } return valor; } private static final Logger LOGGER = LoggerFactory.getLogger(DatatablesHelper.class); }