Implementación de un evaluador de predicados personalizado para el generador de consultas

En este documento se describe cómo ampliar el Query Builder mediante la implementación de un evaluador de predicado personalizado.

Información general

El Generador de consultas ofrece una manera fácil de consultar el repositorio de contenido. AEM viene con un conjunto de evaluadores predicados que le ayudan a consultar sus datos.

Sin embargo, es posible que desee simplificar las consultas mediante la implementación de un evaluador de predicados personalizado que oculte cierta complejidad y garantice una mejor semántica.

Un predicado personalizado también podría realizar otras cosas no directamente posibles con XPath, por ejemplo:

  • Consulta de datos de otro servicio
  • Filtro personalizado basado en un cálculo
NOTA

Se deben tener en cuenta los problemas de rendimiento al implementar un predicado personalizado.

CONSEJO

Puede encontrar ejemplos de consultas en el documento Query Builder.

CONSEJO

Puede encontrar el código de esta página en GitHub

NOTA

Este código vinculado en GitHub y los fragmentos de código de este documento solo se proporcionan con fines de demostración.

Predicar evaluador en detalle

Un evaluador predicado gestiona la evaluación de ciertos predicados, que son las restricciones de definición de una consulta.

Asigna una restricción de búsqueda de nivel superior (como width>200) a una consulta JCR específica que se ajusta al modelo de contenido real (p. ej. metadata/@width > 200). O puede filtrar manualmente los nodos y comprobar sus restricciones.

CONSEJO

Para obtener más información sobre el PredicateEvaluator y el paquete com.day.cq.search, consulte la documentación de Java.

Implementación de un evaluador de predicados personalizado para metadatos de replicación

Como ejemplo, en esta sección se describe cómo crear un evaluador de predicado personalizado que ayude a crear datos basados en los metadatos de replicación:

  • cq:lastReplicated que almacena la fecha de la última acción de replicación
  • cq:lastReplicatedBy que almacena el id del usuario que activó la última acción de replicación
  • cq:lastReplicationAction que almacena la última acción de replicación (por ejemplo, Activación, Desactivación)

Consulta de metadatos de replicación con evaluadores de predicados predeterminados

La siguiente consulta recupera la lista de nodos de la rama /content que han sido activados por admin desde el comienzo del año.

path=/content

1_property=cq:lastReplicatedBy
1_property.value=admin

2_property=cq:lastReplicationAction
2_property.value=Activate

daterange.property=cq:lastReplicated
daterange.lowerBound=2013-01-01T00:00:00.000+01:00
daterange.lowerOperation=>=

Esta consulta es válida pero difícil de leer y no resalta la relación entre las tres propiedades de replicación. La implementación de un evaluador de predicado personalizado reducirá la complejidad y mejorará la semántica de esta consulta.

Objetivos

El objetivo de ReplicationPredicateEvaluator es admitir la consulta anterior utilizando la siguiente sintaxis.

path=/content

replic.by=admin
replic.since=2013-01-01T00:00:00.000+01:00
replic.action=Activate

Agrupar predicados de metadatos de replicación con un evaluador de predicado personalizado ayuda a crear una consulta significativa.

Actualización de dependencias de Maven

CONSEJO

La configuración de nuevos proyectos de AEM, incluido el uso de maven, se explica en detalle en el tutorial de WKND.

Primero debe actualizar las dependencias Maven del proyecto. El PredicateEvaluator forma parte del artefacto cq-search, por lo que debe añadirse al archivo Pom de Maven.

NOTA

El ámbito de la dependencia cq-search se establece en provided porque cq-search será proporcionado por el contenedor OSGi.

El siguiente fragmento muestra las diferencias en el archivo pom.xml, en formato de comparación de diferencias unificado

@@ -120,6 +120,12 @@
             <scope>provided</scope>
         <dependency>
+            <groupid>com.day.cq</groupid>
+            <artifactid>cq-search</artifactid>
+            <version>5.6.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupid>junit</groupid>
             <artifactid>junit</artifactid>
             <version>3.8.1</version></dependency>

Escritura del ReplicationPredicateEvaluator

El proyecto cq-search contiene la clase abstracta AbstractPredicateEvaluator. Esto se puede ampliar con algunos pasos para implementar su propio evaluador de predicados personalizado (PredicateEvaluator).

NOTA

El siguiente procedimiento explica cómo crear una expresión Xpath para filtrar los datos. Otra opción sería implementar el método includes que selecciona los datos en forma de fila. Consulte la documentación de Java para obtener más información.

  1. Cree una nueva clase Java que se extienda com.day.cq.search.eval.AbstractPredicateEvaluator

  2. Anotar la clase con un fragmento @Component similar al que se muestra en formato de comparación de diferencias unificado

    @@ -19,8 +19,11 @@
      */
     package com.adobe.aem.docs.search;
    
    +import org.apache.felix.scr.annotations.Component;
    +import com.day.cq.search.eval.AbstractPredicateEvaluator;
    
    +@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/repli")
     public class ReplicationPredicateEvaluator extends AbstractPredicateEvaluator {
    
     }
    
    NOTA

    El factorydebe ser una cadena única que empiece por com.day.cq.search.eval.PredicateEvaluator/y termine por el nombre del PredicateEvaluator personalizado.

    NOTA

    El nombre del PredicateEvaluator es el nombre del predicado, que se utiliza al crear consultas.

  3. Omitir:

    public String getXPathExpression(Predicate predicate, EvaluationContext context)
    

    En el método override se genera una expresión Xpath basada en el Predicate indicado en el argumento .

Ejemplo de un evaluador de predicados personalizado para metadatos de replicación

La implementación completa de este PredicateEvaluator puede ser similar a la siguiente clase.

/*
 * #%L
 * aem-docs-custom-predicate-evaluator
 * %%
 * Copyright (C) 2013 Adobe Research
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

package com.adobe.aem.docs.search;

import org.apache.felix.scr.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.search.Predicate;
import com.day.cq.search.eval.AbstractPredicateEvaluator;
import com.day.cq.search.eval.EvaluationContext;

@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/repli")

public class ReplicationPredicateEvaluator extends AbstractPredicateEvaluator {

    static final String PE_NAME = "replic";


    static final String PN_LAST_REPLICATED_BY = "cq:lastReplicatedBy";
    static final String PN_LAST_REPLICATED = "cq:lastReplicated";
    static final String PN_LAST_REPLICATED_ACTION = "cq:lastReplicationAction";

    static final String PREDICATE_BY = "by";
    static final String PREDICATE_SINCE = "since";
    static final String PREDICATE_SINCE_OP = " >= ";
    static final String PREDICATE_ACTION = "action";

    Logger log = LoggerFactory.getLogger(getClass());

    /**
     * Returns a XPath expression filtering by replication metadata.
     *
     * @see com.day.cq.search.eval.AbstractPredicateEvaluator#getXPathExpression(com.day.cq.search.Predicate,
     *      com.day.cq.search.eval.EvaluationContext)
     */

    @Override

    public String getXPathExpression(Predicate predicate,
            EvaluationContext context) {

        log.debug("predicate {}", predicate);

        String date = predicate.get(PREDICATE_SINCE);
        String user = predicate.get(PREDICATE_BY);
        String action = predicate.get(PREDICATE_ACTION);

        StringBuilder sb = new StringBuilder();

        if (date != null) {

            sb.append(PN_LAST_REPLICATED).append(PREDICATE_SINCE_OP);
            sb.append("xs:dateTime('").append(date).append("')");

        }

        if (user != null) {

            addAndOperator(sb);
            sb.append(PN_LAST_REPLICATED_BY);
            sb.append("='").append(user).append("'");

        }

        if (action != null) {

            addAndOperator(sb);
            sb.append(PN_LAST_REPLICATED_ACTION);
            sb.append("='").append(action).append("'");

        }

        String xpath = sb.toString();

        log.debug("xpath **{}**", xpath);

        return xpath;

    }

    /**
     * Add an and operator if the builder is not empty.
     *
     * @param sb a {@link StringBuilder} containing the query under construction
     */

    private void addAndOperator(StringBuilder sb) {

        if (sb.length() != 0) {

            sb.append(" and ");

        }

    }

}

En esta página

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now