Show Menu
THEMEN×

Implementieren eines benutzerdefinierten Prädikat-Auswerters für den Query Builder

In diesem Abschnitt ist beschrieben, wie Sie den Query Builder durch Implementieren eines benutzerdefinierten Prädikat-Auswerters erweitern können.

Überblick

Mit dem Query Builder können Sie problemlos das Inhalts-Repository abfragen. Im Lieferumfang sind eine Reihe Prädikat-Auswerter enthalten, die Ihnen den Umgang mit Daten erleichtern.
Sie möchten jedoch vielleicht Abfragen vereinfachen, indem Sie einen benutzerdefinierten Prädikat-Auswerter implementieren, der weniger komplex ist und für eine bessere Semantik sorgt.
Ein benutzerdefiniertes Prädikat ist auch für andere Aufgaben nützlich, die nicht direkt mit XPath ausgeführt werden können, z. B.:
  • Suchen nach Daten und Services
  • Benutzerdefiniertes Filtern basierend auf Berechnungen
Beim Implementieren eines benutzerdefinierten Prädikats müssen Leistungsaspekte berücksichtigt werden.
Beispiele für Abfragen finden Sie im Abschnitt Query Builder .
CODE AUF GITHUB
Den Code dieser Seite finden Sie auf GitHub

Prädikat-Auswerter im Detail

Ein Prädikat-Auswerter ist für die Auswertung bestimmter Prädikate zuständig, die eine Abfrage einschränken.
Dabei wird eine allgemeinere Sucheinschränkung (z. B. "width > 200") einer spezifischen JCR-Abfrage zugeordnet, die mit dem tatsächlichen Inhaltsmodell übereinstimmt (z. B. metadata/@width > 200). Es können auch Knoten manuell gefiltert und deren Einschränkungen überprüft werden.
For more information about the PredicateEvaluator and the com.day.cq.search package see the Java documentation .

Implementieren eines benutzerdefinierten Prädikat-Auswerters für Replikationsmetadaten

In diesem Beispiel wird in diesem Abschnitt beschrieben, wie ein benutzerdefinierter Prädikate-Evaluator erstellt wird, der Daten basierend auf den Replikationsmetadaten unterstützt:
  • cq:lastReplicated speichert die Daten der letzten Replikationsaktion.
  • cq:lastReplicatedBy speichert die ID des Benutzers, der die letzte Replikationsaktion ausgelöst hat.
  • cq:lastReplicationAction speichert die letzte Replikationsaktion (z. B. Aktivierung, Deaktivierung).

Abfragen von Replikationsmetadaten mit Standard-Prädikat-Auswertern

The following query fetches the list of nodes in /content branch that have been activated by admin since the beginning of the year.
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=>=

Diese Abfrage ist zwar gültig, jedoch schwer zu lesen. Außerdem wird die Beziehung zwischen den drei Replikationseigenschaften nicht hervorgehoben. Das Implementieren eines benutzerdefinierten Prädikat-Auswerters reduziert die Komplexität und verbessert die Semantik dieser Abfrage.

Ziele

Ziel des ReplicationPredicateEvaluator ist die Unterstützung der obigen Abfrage durch folgende Syntax:
path=/content

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

Durch die Gruppierung von Replikationsmetadaten wird eine aussagekräftige Abfrage mithilfe eines benutzerspezifischen Prädikatsauswerters erstellt.

Aktualisieren von Maven-Abhängigkeiten

Informationen zum Einrichten neuer AEM-Projekte mit Maven finden Sie in der Dokumentation Erstellen von AEM-Projekten mit Apache Maven .
Sie müssen zunächst die Maven-Abhängigkeiten Ihres Projekts aktualisieren. PredicateEvaluator ist Teil des cq-search -Artefakts und muss zur POM-Datei von Maven hinzugefügt werden.
The scope of the cq-search dependency is set to provided because cq-search will be provided by the OSGi container.
pom.xml
The following snippet shows the differences, in unified diff format
@@ -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>

Schreiben von ReplicationPredicateEvaluator

The cq-search project contains the AbstractPredicateEvaluator abstract class. This can be extended with a few steps to implement your own custom predicate evaluator (PredicateEvaluator ).
Im folgenden Abschnitt wird erläutert, wie Sie einen Xpath -Ausdruck zum Filtern von Daten erstellen. Another option would be to implement the includes method that selects data on a row basis. Weitere Informationen finden Sie in der Java-Dokumentation .
  1. Erstellen Sie eine neue Java-Klasse zum Erweitern von com.day.cq.search.eval.AbstractPredicateEvaluator
  2. Annotate your class with a @Component like the following
    src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java
    The following snippet shows the differences, in unified diff format
@@ -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 {

 }

The factory must be a unique string starting with com.day.cq.search.eval.PredicateEvaluator/ and ending with the name of your custom PredicateEvaluator .
Der Name des PredicateEvaluator ist der Name des Prädikats, das zum Erstellen von Abfragen verwendet wird.
  1. Überschreibung:
    public String getXPathExpression(Predicate predicate, EvaluationContext context)
    
    
    Bei der Überschreibmethode erstellen Sie einen Xpath -Ausdruck basierend auf dem im Argument angegebenen Predicate .

Beispiel für einen benutzerdefinierten Prädikat-Auswerter für Replikationsmetadaten

Die vollständige Implementierung dieses PredicateEvaluator kann der folgenden Klasse ähnlich sein.
src/main/java/com/adobe/aem/docs/search/ReplicationPredicateEvaluator.java
/*
 * #%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 ");

        }

    }

}