
org.javabeanstack.web.jsf.controller.AbstractDataController Maven / Gradle / Ivy
The newest version!
/*
* JavaBeanStack FrameWork
*
* Copyright (C) 2018 Jorge Enciso
* Email: [email protected]
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.javabeanstack.web.jsf.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.javabeanstack.data.IDataNativeQuery;
import org.javabeanstack.data.IDataQueryModel;
import org.primefaces.event.SelectEvent;
import org.javabeanstack.datactrl.AbstractDataObject;
import org.javabeanstack.web.util.FacesContextUtil;
import org.javabeanstack.data.IDataRow;
import org.javabeanstack.data.IDataSet;
import org.javabeanstack.datactrl.IDataObject;
import org.javabeanstack.datactrl.uicomponents.IDatatable;
import org.javabeanstack.security.model.IUserSession;
import org.javabeanstack.util.Fn;
import org.javabeanstack.error.ErrorManager;
import org.javabeanstack.util.Strings;
import org.javabeanstack.xml.IXmlDom;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.javabeanstack.events.ICtrlEvents;
import org.javabeanstack.model.IAppObjectAuth;
import org.javabeanstack.web.util.AppResourceSearcher;
/**
* Controller para los ABMs de las tablas o vistas, hereda funcionalidades de
* AbstractDataObject
*
* @author Jorge Enciso
* @param
*/
public abstract class AbstractDataController extends AbstractDataObject {
/**
* Lista de registros de la selección de datos en un proceso que trae los
* datos por bloque (pagina a pagina)
*/
private LazyDataRows lazyDataRows;
private Boolean noLazyRowsLoad = false;
/**
* Guarda los registros seleccionados en el UIDataTable o grilla de datos
*/
private T[] rowsSelected;
/**
* Se asigna cuando se selecciona un registro en la grilla de datos
*/
private T rowSelected;
/**
* Registros resultante de la aplicación de un proceso de filtrado
*/
private List rowsFiltered;
/**
* El contexto del servet jsf
*/
private FacesContextUtil facesCtx = new FacesContextUtil();
/**
* identificador del registro de la tabla normalmente se pasa desde otro
* proceso para realizar una operación sobre el mismo
*/
private Object id;
/**
* Operación a ejecutar, (agregar, modificar, borrar, consultar etc)
*/
private String action = "";
private ICtrlEvents ctrlEvents = new CtrlEventLocal();
private String xmlResourcePath = "";
private IXmlDom xmlResource;
/**
* Lista de campos de busquedas los cuales serán parte del filtro en el
* metodo onCompleteText
*/
private final Map completeTextSearchFields = new TreeMap(String.CASE_INSENSITIVE_ORDER);
public AbstractDataController() {
}
public AbstractDataController(Class type) {
this.setType(type);
}
protected abstract AppResourceSearcher getAppResource();
public abstract IDatatable getDataTable();
public abstract void configDataTables();
public abstract void configDataTables(IDatatable dataTable, String nodeName);
public String getXmlResourcePath() {
return xmlResourcePath;
}
public void setXmlResourcePath(String xmlResourcePath) {
this.xmlResourcePath = xmlResourcePath;
}
public Integer checkAuthorization(String action){
return IAppObjectAuth.ALLOWED;
}
public IXmlDom getXmlResource() {
if (xmlResource == null) {
xmlResource = getAppResource().getXmlDom(xmlResourcePath, "XML", null);
}
return xmlResource;
}
public void setXmlResource(T context) {
//Leer de la tabla AppResourceSearcher o de un xml
xmlResource = getAppResource().getXmlDom(xmlResourcePath, "XML", null);
}
public ICtrlEvents getCtrlEvents() {
return ctrlEvents;
}
public void setCtrlEvents(ICtrlEvents ctrlEvents) {
this.ctrlEvents = ctrlEvents;
}
/**
* Acción a realizar o en ejecución, (agregar, modificar, borrar, consultar
* etc)
*
* @return valor de action (agregar, modificar, borrar, consultar etc)
*/
public String getAction() {
return action;
}
/**
* Devuelve la acción a realizar en el registro actual.
*
* @return acción a realizar en el registro actual.
*/
public int getRowAction() {
if (getRow() == null) {
return 0;
}
return getRow().getAction();
}
/**
* Devuelve el identificador del registro de la tabla normalmente se pasa
* desde otro proceso para realizar una operación sobre el mismo
*
* @return identificador del registro de la tabla
*/
public Object getId() {
return id;
}
/**
* Asigna el identificador del registro de la tabla para realizar alguna
* operación sobre el registro
*
* @param id el identificador del registro de la tabla
*/
public void setId(Object id) {
this.id = id;
}
/**
* Devuelve la instancia de FacesContext
*
* @return la instancia de FacesContext
*/
public FacesContextUtil getFacesCtx() {
if (facesCtx == null) {
facesCtx = new FacesContextUtil();
}
return facesCtx;
}
public Boolean getNoLazyRowsLoad() {
return noLazyRowsLoad;
}
public void setNoLazyRowsLoad(Boolean noLazyRowsLoad) {
this.noLazyRowsLoad = noLazyRowsLoad;
}
/**
* Devuelve una lista de Registros de la selección de datos en un proceso
* que trae registros por bloque (pagina a pagina)
*
* @return
*/
public LazyDataRows getLazyDataRows() {
if (lazyDataRows == null) {
lazyDataRows = new LazyDataRows(this);
}
return lazyDataRows;
}
/**
* Asigna la lista de registros
*
* @param lazyDataRows
*/
public void setLazyDataRows(LazyDataRows lazyDataRows) {
this.lazyDataRows = lazyDataRows;
}
/**
* Devuelve el registro seleccionado en la grilla que originalmente fue
* asignado en el metodo onRowSelected()
*
* @return registro seleccionado en la grilla.
*/
public T getRowSelected() {
return rowSelected;
}
/**
* Asigna en forma manual el atributo rowSelected.
*
* @param rowSelected
*/
public void setRowSelected(T rowSelected) {
try {
if (rowSelected == null) {
this.rowSelected = null;
} else {
this.rowSelected = (T) rowSelected;
}
} catch (Exception ex) {
ErrorManager.showError(ex, Logger.getLogger(this.getClass()));
}
}
/**
* Devuelve los registros seleccionados en la grilla
*
* @return registros seleccionados en la grilla.
*/
public T[] getRowsSelected() {
return rowsSelected;
}
/**
* Asigna manualmente los registros seleccionados
*
* @param rowsSelected
*/
public void setRowsSelected(T[] rowsSelected) {
this.rowsSelected = rowsSelected;
}
/**
* Devuelve los Registros que fuerón objeto de un proceso de filtrado en la
* grilla
*
* @return registros filtrados.
*/
public List getRowsFiltered() {
return rowsFiltered;
}
/**
* Asigna la lista de registros filtrados.
*
* @param rowsFiltered
*/
public void setRowsFiltered(List rowsFiltered) {
this.rowsFiltered = rowsFiltered;
}
/**
* Devuelve la cantidad total de registros
*
* @return cantidad total de registros de la sentencia
*/
public Integer getRowsCount() {
if (lazyDataRows != null) {
return lazyDataRows.getRowCount();
} else if (rowsFiltered == null) {
return getDataRows().size();
}
return rowsFiltered.size();
}
public IUserSession getUserSession() {
return facesCtx.getUserSession();
}
public Long getUserId() {
return facesCtx.getUserId();
}
/**
* Devuelve el nombre del archivo xhtml linkeado a este controller
*
* @return archivo xhtml linkeado a este controller
*/
public String getWebFileName() {
String uri = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
int indexat = uri.lastIndexOf("/");
uri = uri.substring(indexat + 1).toLowerCase();
return uri;
}
public Map getCompleteTextSearchFields() {
return completeTextSearchFields;
}
/**
* Se ejecuta al seleccionar un registro en la grilla
*
* @param event
*/
public void onRowSelect(SelectEvent event) {
if (ctrlEvents != null) {
ctrlEvents.onRowSelect(this, event);
}
}
/**
* Se ejecuta posterior a la ejecución del filtrado de la grilla
*/
public void onRowFilter() {
if (ctrlEvents != null) {
ctrlEvents.onRowFilter(this);
}
}
/**
* Se ejecuta en el evento completetext de algunos controles.
*
* @param text valor introducido.
* @return lista de registros que cumplen la condición del filtro.
*/
public List onCompleteText(String text) {
if (ctrlEvents != null) {
return ctrlEvents.onCompleteText(this, text);
}
return null;
}
/**
* Agrega campos a la lista de busquedas las cuales serán parte del filtro.
*
* @param field campo
*/
public void addCompleteFieldSearch(String field) {
addCompleteFieldSearch(field, "like");
}
/**
* Agrega campos a la lista de busquedas las cuales serán parte del filtro.
*
* @param field campo
* @param operator operador ("like","=")
*/
public void addCompleteFieldSearch(String field, String operator) {
this.completeTextSearchFields.put(field, operator);
}
/**
* Su función es crear el filtro que se utilizado en la selección de datos.
*
* @param text dato introducido.
* @return filtro que se utilizará en la selección de datos en el where.
*/
protected String getCompleteTextFilter(String text) {
String filter = "";
String separador = "";
for (Map.Entry entry : completeTextSearchFields.entrySet()) {
if ("like".equalsIgnoreCase(entry.getValue().trim())) {
filter += separador + "LOWER(" + entry.getKey() + ")" + " ";
filter += entry.getValue() + " '%" + text.trim().toLowerCase() + "%' ";
} else {
filter += separador + entry.getKey() + " " + entry.getValue() + "'" + text + "'";
}
separador = " or ";
}
return filter;
}
/**
* Se ejecuta en doAction al iniciar cualquier operación (edición, borrado,
* altas)
*
* @param operation operación ("agregar","modificar","consultar" etc)
* @param success
*/
protected void initAction(String operation, boolean success) {
if (success) {
if (Fn.inList(operation.toLowerCase(), "1", "agregar")) {
operation = "insert";
}
if (Fn.inList(operation.toLowerCase(), "2", "modificar")) {
operation = "update";
}
if ("consult".equals(operation.toLowerCase())) {
operation = "view";
}
action = operation;
noLazyRowsLoad = true;
}
}
/**
* Se ejecuta posterior a presionar sobre un boton de agregar, editar,
* borrar, consultar y otros.
*
* @param operation
* @return verdadero si se le permite (tiene permiso) realizar la operación
* deseada
*/
public boolean doAction(String operation) {
boolean result = true;
//Verificar permiso
Integer authorization = checkAuthorization(operation);
if (authorization.equals(IAppObjectAuth.DENIED)){
facesCtx.showWarn("No esta autorizado para realizar esta operación");
action = "";
return false;
}
action = operation;
// Si no es agregar nuevo registro refrescar el registro actual
if (!Fn.inList(operation.toLowerCase(), "insert", "agregar", "1")) {
refreshRow();
}
switch (operation.toLowerCase()) {
case "1":
case "insert":
case "agregar":
result = this.allowAction(IDataRow.AGREGAR);
if (result) {
rowsSelected = null;
result = insertRow();
}
break;
case "2":
case "update":
case "modificar":
case "confirm":
case "anular":
result = this.allowAction(IDataRow.MODIFICAR);
break;
case "3":
case "delete":
case "borrar":
result = this.allowAction(IDataRow.BORRAR);
break;
case "consultar":
case "consult":
case "view":
case "read":
result = this.allowAction(IDataRow.CONSULTAR);
break;
case "-5":
case "imprimir":
case "print":
result = this.allowAction(IDataRow.IMPRIMIR);
break;
}
if (getErrorApp() != null) {
facesCtx.showError("Error", getErrorApp().getMessage());
result = false;
action = "";
} else if (!result) {
facesCtx.showWarn("No es posible realizar esta operación");
action = "";
}
initAction(operation, result);
facesCtx.addCallbackParam("result", result);
if (result) {
String refreshUI = Fn.nvl((String)getProperty("AFTERACTION_REFRESH_UICOMPONENT"),"");
refreshUIComponent(refreshUI);
}
return result;
}
/**
* Retorna una bandera comunicando a la vista que habilite o desabilite la
* edición de datos de un control.
*
* @param fieldName campo
* @return verdadero o falso para habilitar o desabilitar un control de
* datos.
*/
public boolean allowEditField(String fieldName) {
if (getRow() == null) {
return false;
}
if (Fn.nvl(fieldName, "").isEmpty()) {
return false;
}
return !(getRow().getAction() != IDataRow.AGREGAR
&& getRow().getAction() != IDataRow.MODIFICAR);
}
/**
* Retorna un label según la acción a realizar
*
* @return una etiqueta o label según la acción a realizar.
*/
public String getActionLabel() {
if (getAction().equals("confirm")) {
return "Confirmar";
}
if (getAction().equals("delete")) {
return "Eliminar";
}
if (getAction().equals("anular")) {
return "Anular";
}
return "Aceptar";
}
/**
* Busca el valor mas alto de un campo en una tabla dada.
*
* @param table nombre de la tabla en la base.
* @param fieldName nombre del campo.
* @param filter filtro de busqueda.
* @param parameters parametros a reemplazar en los filtros.
* @return el valor más alto del campo de la tabla solicitada.
*/
public Object getNewValue(String table, String fieldName, String filter, Map parameters) {
IDataNativeQuery query = getDAO().newDataNativeQuery();
try {
List data
= query.select("max(" + fieldName + ") as maximo")
.from(table)
.where(Fn.nvl(filter, ""), parameters)
.execQuery();
if (!data.isEmpty() && data.get(0) != null) {
return data.get(0).getColumn("maximo");
}
} catch (Exception ex) {
ErrorManager.showError(ex, Logger.getLogger(getClass()));
}
return null;
}
/**
* Se deberia ejecutar al cambiar un valor en un control de datos
*
* @param fieldname nombre del campo asociado al control.
*/
public void onChange(String fieldname) {
}
/**
* Se deberia ejecutar al cambiar el foco de un control en el formulario
*
* @param fieldname nombre del campo asociado al control.
*/
public void onBlur(String fieldname) {
}
public boolean checkFieldValue(String fieldname) {
return true;
}
/**
* Refresca el valor de un control asociado a un campo.
*
* @param fieldname
*/
public void refresh(String fieldname) {
}
/**
* Actualiza la base de datos.
*
* @return verdadero si tuvo exito o falso si no.
*/
public boolean update() {
boolean success = super.update(false);
afterAction(success);
// Devolver resultado de la grabación
return success;
}
/**
* Actualiza la base de datos.
*
* @param dataSet
* @return verdadero si tuvo exito o falso si no.
*/
@Override
public boolean update(IDataSet dataSet) {
boolean success = super.update(dataSet);
afterAction(success);
// Devolver resultado de la grabación
return success;
}
/**
* Revierte cualquier modificación hecha a los datos, los deja como esta en
* la base.
*
* @return verdadero si no exito o falso si no.
*/
@Override
public boolean revert() {
boolean success = super.revert();
action = "revert";
afterAction(success);
// Devolver resultado de la reversión
return success;
}
/**
* Refresca el valor de un control de datos.
*/
protected void refreshUIComponent() {
String refreshUIComponent = (String) getProperty("refreshUIComponent");
if (!Strings.isNullorEmpty(refreshUIComponent)) {
getFacesCtx().refreshView(refreshUIComponent);
}
}
/**
* Refresca un control de datos en la vista.
*
* @param refreshUIComponent control de datos a refrescar.
*/
protected void refreshUIComponent(String refreshUIComponent) {
if (!Strings.isNullorEmpty(refreshUIComponent)) {
getFacesCtx().refreshView(refreshUIComponent);
}
}
/**
* Se ejecuta al finalizar toda operación, normalmente al final de Update()
* o Revert()
*
* @param success verdadero o falso en las operaciones update o revert.
*/
protected void afterAction(boolean success) {
facesCtx.addCallbackParam("result", success);
if (getErrorApp() != null) {
facesCtx.showError("Error", getErrorApp().getMessage());
} else if (!success) {
facesCtx.showError("Error", getRow().getErrors());
}
// Esto con el fin de que no se ejecute el metodo load del lazydatarows
// en caso de que se actualize un dataTable
getFacesCtx().setAttribute("nolazyload", Boolean.TRUE);
if (success) {
if (Fn.inList(action, "3", "delete", "borrar")) {
facesCtx.showWarn("Borrado realizado con exito");
} else if (action.equals("revert")) {
facesCtx.showInfo("Operación cancelada");
} else {
facesCtx.showInfo("Operación realizada con exito");
}
if (getRow() != null){
setRowSelected(getRow());
}
//Renderizar componentes
refreshUIComponent((String)getProperty("AFTERACTION_REFRESH_UICOMPONENT"));
}
if (Fn.toLogical(getProperty("AFTERINSERT_INSERT_AGAIN"))) {
//Para inserción multiples
if (success && Fn.inList(action, "1", "insert", "agregar")) {
doAction("insert");
return;
}
}
if (success && Fn.toLogical(getProperty("AFTERACTION_REFRESH_ROW"))) {
//Refrescar el registro despues de la grabación
if (success && Fn.inList(action, "2", "update", "modificar")) {
refreshRow();
}
}
if (success) {
action = "";
}
noLazyRowsLoad = false;
}
public String logout() {
return facesCtx.logout();
}
/**
* Se utiliza en el LazyDataRows, en este metodo se implementa en forma
* personalizada el filtro a utilizar posteriormente en la selección de
* datos.
*
* @param filters nombre de campos y valores.
* @return filtro personalizado.
*/
public String onGetFilterString(Map filters) {
return "";
}
/**
* Copia los datos del registro actual de la vista al objeto tabla
*
* @param
* @param
* @param target controller destino donde almacena el objeto mapeado a la
* tabla
* @throws Exception
*/
protected void copyTo(K target) throws Exception {
target.insertRow();
T row = (T) target.getRow();
row.setAction(getRow().getAction());
row = this.getDAO().getDataService().copyTo(getUserSession().getSessionId(), getRow(), row);
List dataRows = new ArrayList();
dataRows.add(row);
target.setDataRows(dataRows);
target.moveFirst();
}
class CtrlEventLocal implements ICtrlEvents {
@Override
public void onRowSelect(IDataObject context, Object event) {
int recno = getDataRows()
.indexOf((T) ((org.primefaces.event.SelectEvent) event).getObject());
if (context.goTo(recno)) {
rowSelected = getRow();
}
}
@Override
public void onRowFilter(IDataObject context) {
String tableTextFooter = (String) getProperty("tableTextFooter");
if (Strings.isNullorEmpty(tableTextFooter)) {
return;
}
UIComponent text = facesCtx.findComponent(tableTextFooter);
if (lazyDataRows != null) {
text.getAttributes().put("value", lazyDataRows.getRowCount());
} else if (rowsFiltered == null) {
text.getAttributes().put("value", getDataRows().size());
} else {
text.getAttributes().put("value", rowsFiltered.size());
}
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(tableTextFooter);
}
@Override
public void onChange(IDataObject context, String fieldname) {
}
@Override
public List onCompleteText(IDataObject context, String text) {
if (text.isEmpty()) {
setFilter("");
} else {
String filter = getCompleteTextFilter(text);
setFilter(filter);
}
requery();
List rows = getDataRows();
return rows;
}
}
protected boolean beforeLazyRowsLoad(){
return true;
}
public void doFilter(String table, String filterTag) {
//Implementar en clases derivadas.
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy