En OpenXava v4.x puedes usar el viejo
proyecto AccessTracking. Otra alternativa para auditar cambios es
Hibernate Envers.
OpenXava tiene un mecanismo para registrar cualquier cambio hecho por los
usuarios y también accesos de lectura. Este mecanismo es totalmente
configurable y está desactivado por defecto.
Implementación
propia del registro de acceso
Para registra el acceso a los datos necesitas un
IAccessTrackerProvider (una interfaz de
org.openxava.util).
Crear una es fácil, simplemente crea una clase que implemente la interfaz,
como la siguiente:
package org.openxava.util;
import java.io.*;
import java.util.*;
import org.apache.commons.logging.*;
import org.openxava.application.meta.*;
public class LogAccessTrackerProvider implements IAccessTrackerProvider {
private static Log log = LogFactory.getLog(LogAccessTrackerProvider.class);
private static String fileName;
public void consulted(String modelName, Map key) {
log("CONSULTED: user=" + Users.getCurrent() + ", model=" + modelName + ", key=" + key);
}
public void created(String modelName, Map key) {
log("CREATED: user=" + Users.getCurrent() + ", model=" + modelName + ", key=" + key);
}
public void modified(String modelName, Map key, Map<String, Object> oldChangedValues, Map<String, Object> newChangedValues) {
StringBuffer changes = new StringBuffer();
for (String property: oldChangedValues.keySet()) {
if (changes.length() > 0) changes.append(", ");
changes.append(Labels.getQualified(property));
changes.append(": ");
changes.append(Strings.toString(oldChangedValues.get(property)));
changes.append(" --> ");
changes.append(Strings.toString(newChangedValues.get(property)));
}
log("MODIFIED: user=" + Users.getCurrent() + ", model=" + modelName + ", key=" + key + ", changes=" + changes);
}
public void removed(String modelName, Map key) {
log("REMOVED: user=" + Users.getCurrent() + ", model=" + modelName + ", key=" + key);
}
private static void log(String line) {
try {
createFileIfNotExist();
FileOutputStream f = new FileOutputStream(getFileName(), true);
PrintStream p = new PrintStream(f);
p.println(line);
p.close();
f.close();
}
catch (Exception ex) {
log.warn(XavaResources.getString("log_tracker_log_failed"), ex);
}
}
private static void createFileIfNotExist() throws Exception {
Files.createFileIfNotExist(getFileName());
}
private static String getFileName() {
if (fileName == null) {
Collection applicationNames = MetaApplications.getApplicationsNames();
String app = "openxava-app";
if (!applicationNames.isEmpty()) app = applicationNames.iterator().next().toString().toLowerCase();
fileName = Files.getOpenXavaBaseDir() + app + "-access.log";
}
return fileName;
}
}
Esta es la implementación más simple posible, simplemente registra los
accesos en un archivo log. Fíjate que has de implementar cuatro simples
métodos:
consulted(),
created(),
modified()
y
removed(). A paritir de v7.2 también tienes un método
executed()
que puedes implementar opcionalmente,
executed() se llama cada vez
se ejecuta una acción, pero excluyendo las acciones CRUD y otras acciones
básicas incluidas en OpenXava. Puedes escribir tu propia implementación
para grabar los acceso a la base de datos, por ejemplo. El proveedor de
registro de arriba,
LogTrackerAccessProvider, se incluye en
OpenXava, en el paquete
org.openxava.util, por lo que puedes
usarlo tal cual si no necesitas más.
Registrar
el proveedor de registro
Para que tu proveedor de registro funcione lo has de declarar en el
xava.properties
de tu proyecto, usando la entrada
accessTrackerProvidersClasses:
accessTrackerProvidersClasses=org.openxava.util.LogAccessTrackerProvider
Puedes definir varios proveedores de registros separados por comas.
Ahora, todos los cambios y lecturas hechos por los usuarios añadirán una
línea en
.openxava/yourapplication-accesss.log.
Notificar
tus propios cambios
Por defecto, todos la cambios hechos vía
MapFacade, lo que
incluye la creación, consulta, modificación y borrado (en la entidad
principal y colecciones) en un módulo estándar de OpenXava. Además, los
editores incluidos en OpenXava, tal como
Discussion,
ImagesGallery
o
Files también notifican sus cambios. Sin embargo, si accede a
los datos desde tu propio código usando JPA o JDBC directamente deberías
notifica el acceso usando la clase
AccessTracker de
org.openxava.util.
Por ejemplo:
crearFacturaConJPA(getView().getKeyValues(), getView().getValues()); // Aquí guardas a tu manera
AccessTracking.created("Invoice", getView().getKeyValues()); // HAS DE AÑADIR ESTA LÍNEA