Ir al contenido

Crear su propio plugin FormInterceptor

Puede crear su propio plugin de interceptor de formulario para interceptar todos los métodos add, set y get.

Descripción de las funcionalidades comunes que puede implementar este tipo de plugin:

  1. Interceptar los valores de las propiedades antes de la creación (add), lo que permite:
    1. Actualizar valores
    2. Validar valores
    3. Autocompletar valores
  2. Interceptar las propiedades o elementos de formulario en ‘get’ para:
    1. Eliminar valores (campos)
    2. Cambiar el comportamiento de la interfaz de los elementos de formulario (marcar campos como solo lectura, ocultar campos, etc.)
    3. Crear elementos de formulario al vuelo que no se guardarán en la base de datos (requiere filtrado en las etapas add y set)
    4. Aplicar una máscara a los valores que se muestran (proteger valores críticos).
    5. Cambiar el orden de los elementos de formulario
  3. Interceptar los valores de las propiedades antes de la actualización (set) para:
    1. Actualizar valores
    2. Validar valores
    3. Autocompletar valores

Condiciones:

  • La nueva clase Form Interceptor debe implementar la interfaz “FormInterceptor”.
  • La nueva clase Form Interceptor debe declararse en el paquete “com.openkm.plugin.form.interceptor”.
  • La nueva clase Form Interceptor debe anotarse con@PluginImplementation”.
  • La nueva clase Form Interceptor debe extender “BasePlugin”.

Interfaz FormInterceptor:

package com.openkm.plugin.form.interceptor;
import com.openkm.bean.form.FormElement;
import com.openkm.core.ValidationFormException;
import net.xeoh.plugins.base.Plugin;
import java.util.List;
import java.util.Map;
public interface FormInterceptor extends Plugin {
String getName();
void add(String uuid, String grpName, Map<String, String> properties) throws ValidationFormException;
void get(String uuid, String grpName, Map<String, String> properties, List<FormElement> formElements, boolean useDefaultValue, boolean autocomplete);
void set(String uuid, String grpName, Map<String, String> properties) throws ValidationFormException;
}

La nueva clase debe cargarse en el paquete com.openkm.plugin.form.interceptor porque el sistema de plugins de la aplicación intentará cargarla desde ahí.

Método Tipo Descripción
getName() String El método devuelve el nombre del plugin.
add(String uuid, String grpName, Map<String, String> properties) void Intercepta la acción de añadir metadatos.
get(String uuid, String grpName, Map<String, String> properties, List formElements, boolean useDefaultValue, boolean autocomplete) void Intercepta la acción de obtener metadatos.
set(String uuid, String grpName, Map<String, String> properties) void Intercepta la acción de establecer metadatos.

Ejemplo de implementación de FormInterceptor

Sección titulada «Ejemplo de implementación de FormInterceptor»

Definición de metadatos:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE property-groups PUBLIC "-//OpenKM//DTD Property Groups 3.14//EN"
"http://www.openkm.com/dtd/property-groups-3.14.dtd">
<property-groups>
<property-group label="Consulting" name="okg:consulting" interceptorClassName="com.openkm.plugin.form.interceptor.SampleFormInterceptor">
<input label="Input label" name="okp:consulting.input1" />
<separator label="Separator label" name="okp:consulting.separator" />
<input label="Input label" name="okp:consulting.input2" />
</property-group>
</property-groups>

En el siguiente plugin de ejemplo, se aplican distintas modificaciones a los metadatos solo durante las acciones add, get y set para un usuario con ID “test”. Le sugerimos probar el ejemplo con este usuario y con otro distinto.

package com.openkm.plugin.form.interceptor;
import com.openkm.bean.form.FormElement;
import com.openkm.bean.form.Input;
import com.openkm.bean.form.ValidationError;
import com.openkm.core.DatabaseException;
import com.openkm.core.PathNotFoundException;
import com.openkm.core.ValidationFormException;
import com.openkm.db.service.NodeBasePropertiesSrv;
import com.openkm.plugin.BasePlugin;
import com.openkm.principal.PrincipalUtils;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@PluginImplementation
public class SampleFormInterceptor extends BasePlugin implements FormInterceptor {
private static final Logger log = LoggerFactory.getLogger(SampleFormInterceptor.class);
private final String TEST_USER = "test";
@Autowired
private NodeBasePropertiesSrv nodeBasePropertiesSrv;
@Override
public String getName() {
return "SampleFormInterceptor";
}
/**
* Description of common features allowed to be implemented by this plugin type:
* 1. intercept the values of the properties before creation (add) what allows to:
* - update values
* - validate values
* - autocomplete values
* <p>
* 2. Intercept get properties or form elements to:
* - remove values ( fields )
* - change UI behaviour of form elements ( set fields as read-only, hide fields, etc )
* - create form elements on the fly what will not be keep in the database ( requires filtering in add and set stages )
* - apply mask to values to be displayed ( protect critical values )
* - change the order of the form elements
* <p>
* 3. intercept the values of the properties before update (set) to:
* - update values
* - validate values
* - autocomplete values
**/
@Override
public void add(String uuid, String grpName, Map<String, String> properties) throws ValidationFormException {
log.info("add({}, {}, {})", uuid, grpName, properties);
String userId = PrincipalUtils.getUser();
if (TEST_USER.equals(userId)) {
// Iterate through the properties map and log each property individually
log.info("Properties in group '{}' for node '{}':", grpName, uuid);
for (Map.Entry<String, String> entry : properties.entrySet()) {
log.info(" Property - Key: '{}', Value: '{}'", entry.getKey(), entry.getValue());
// update the value of the property with the key "okp:consulting.input1"
if ("okp:consulting.input1".equals(entry.getKey())) {
properties.put(entry.getKey(), entry.getValue() + " ( Updated by SampleFormInterceptor at add )");
} else if ("okp:consulting.input2".equals(entry.getKey())) {
String valueInput2 = entry.getValue();
if (StringUtils.isEmpty(valueInput2) || valueInput2.length() < 4) {
// Show error in UI
Map<String, List<ValidationError>> errors = new HashMap<>();
List<ValidationError> validationErrors = new ArrayList<>();
ValidationError validationError = new ValidationError();
validationError.setErrorMessage("Field input2 is mandatory and must have at least 4 characters");
validationError.setPropertyName("okp:consulting.input2");
validationError.setErrorCode("ERROR-003345");
validationError.setPropertyLabel("Input label 2");
validationError.setUuid(uuid);
validationErrors.add(validationError);
errors.put("Validation was not successfully", validationErrors);
throw new ValidationFormException(errors);
}
}
}
}
}
@Override
public void get(String uuid, String grpName, Map<String, String> properties, List<FormElement> formElements, boolean useDefaultValue,
boolean autocomplete) {
// Use default value is true when showing form elements before adding the metadata group
String userId = PrincipalUtils.getUser();
if (TEST_USER.equals(userId)) {
if (properties != null) {
properties.remove("okp:consulting.input1");
properties.put("okp:consulting.input3", "On the fly field");
}
if (CollectionUtils.isNotEmpty(formElements)) {
formElements.removeIf(formElement -> "okp:consulting.input1".equals(formElement.getName()));
// Add form element on the fly
Input input = new Input();
input.setName("okp:consulting.input3");
input.setLabel("Input label 3");
input.setType("text");
input.setValue("On the fly field");
input.setReadonly(true);
formElements.add(input);
}
}
}
@Override
public void set(String uuid, String grpName, Map<String, String> properties) throws ValidationFormException {
log.info("set({}, {}, {})", uuid, grpName, properties);
String userId = PrincipalUtils.getUser();
if (TEST_USER.equals(userId)) {
// Because the parameter "okp:consulting.input1" is not in the properties map, it will be added to the map
// to keep the properties map consistent with the form elements in the database
Map<String, String> currentProperties;
try {
currentProperties = nodeBasePropertiesSrv.getProperties(uuid, grpName, true);
} catch (PathNotFoundException | DatabaseException e) {
throw new RuntimeException(e);
}
if (currentProperties.containsKey("okp:consulting.input1")) {
properties.put("okp:consulting.input1", properties.get("okp:consulting.input1"));
}
if (properties.containsKey("okp:consulting.input2")) {
properties.put("okp:consulting.input2", properties.get("okp:consulting.input2"));
}
if (properties.containsKey("okp:consulting.input2")) {
String valueInput2 = properties.get("okp:consulting.input2");
if (StringUtils.isEmpty(valueInput2) || valueInput2.length() < 4) {
// Show error in UI
Map<String, List<ValidationError>> errors = new HashMap<>();
List<ValidationError> validationErrors = new ArrayList<>();
ValidationError validationError = new ValidationError();
validationError.setErrorMessage("Field input2 is mandatory and must have at least 4 characters");
validationError.setPropertyName("okp:consulting.input2");
validationError.setErrorCode("ERROR-003345");
validationError.setPropertyLabel("Input label 2");
validationError.setUuid(uuid);
validationErrors.add(validationError);
errors.put("Validation was not successfully", validationErrors);
throw new ValidationFormException(errors);
}
}
}
}
}