All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.search.eval.TypePredicateEvaluator Maven / Gradle / Ivy

/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.search.eval;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.query.Row;

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

import com.day.cq.search.Predicate;
import com.day.cq.search.facets.FacetExtractor;
import com.day.cq.search.facets.extractors.DistinctValuesFacetExtractor;

/**
 * Restricts results to a specific JCR node type, both primary node type or mixin type.
 * This will also find subtypes of that node type. Note that repository search indexes
 * need to cover the node types for efficient execution.
 *
 * 

* Supports facet extraction. Will provide buckets for each unique type in the results. * *

Name:

* type * *

Properties:

*
*
type
*
node type or mixin name to search for, for example cq:Page
*
* * @since 5.2 */ @Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/type") public class TypePredicateEvaluator extends AbstractPredicateEvaluator { private static final Logger log = LoggerFactory.getLogger(TypePredicateEvaluator.class); public static final String TYPE = "type"; protected static final String NO_SUCH_NODETYPE = TypePredicateEvaluator.class.getName() + ".no-such-nodetype."; protected static final String NODETYPE_FOUND = TypePredicateEvaluator.class.getName() + ".nodetype-found."; @Override public String getXPathExpression(Predicate p, EvaluationContext context) { if (!p.hasNonEmptyValue(TYPE)) { return null; } final String typeName = p.get(TYPE); List searchNodeTypes = new ArrayList(); try { final NodeTypeManager nodeTypeManager = context.getSession().getWorkspace().getNodeTypeManager(); NodeType nodeType; try { nodeType = nodeTypeManager.getNodeType(typeName); } catch (NoSuchNodeTypeException ne) { log.warn("Node type '" + typeName + "' not found"); return null; } searchNodeTypes.add(nodeType); searchNodeTypes.addAll(getDescendentNodeTypes(nodeType, nodeTypeManager)); } catch (RepositoryException e) { log.debug("could not find child node types for '" + typeName + "'", e); } // enclose in parentheses as the result must be combinable with "and" StringBuffer xpath = new StringBuffer(); xpath.append("("); for (NodeType nt : searchNodeTypes) { // containing more than just the "(" if (xpath.length() > 1) { xpath.append(" or "); } if (nt.isMixin()) { xpath.append("@").append(JcrConstants.JCR_MIXINTYPES); } else { xpath.append("@").append(JcrConstants.JCR_PRIMARYTYPE); } xpath.append(" = '").append(nt.getName()).append("'"); } xpath.append(")"); return xpath.toString(); } @Override public boolean includes(Predicate p, Row row, EvaluationContext context) { if (!p.hasNonEmptyValue(TYPE)) { return true; } final String type = getType(p, context); if (type == null) { // node type does not exist return false; } Node node = context.getNode(row); try { return node.isNodeType(type); } catch (RepositoryException e) { log.error("Problem while checking node for node type '" + p.get(TYPE) + "'", e); } return false; } /** * Returns and validates the type from the predicate. If it is not an * existing node type, it will return null. */ public static String getType(Predicate p, EvaluationContext context) { final String type = p.get(TYPE); // quick fail if we noted earlier that this type does not exist if (context.get(NO_SUCH_NODETYPE + type) != null) { return null; } else if (context.get(NODETYPE_FOUND + type) == null) { // check if we checked the node type already try { final NodeTypeManager nodeTypeManager = context.getSession().getWorkspace().getNodeTypeManager(); try { nodeTypeManager.getNodeType(type); } catch (NoSuchNodeTypeException ne) { log.warn("Node type '" + type + "' not found"); // mark non-existing context.put(NO_SUCH_NODETYPE + type, true); return null; } // mark node type found and valid context.put(NODETYPE_FOUND + type, true); } catch (RepositoryException e) { log.error("Problem while checking node for node type '" + p.get(TYPE) + "'", e); return null; } } return type; } @Override public boolean canXpath(Predicate p, EvaluationContext context) { return true; } @Override public boolean canFilter(Predicate p, EvaluationContext context) { return true; } @Override public String[] getOrderByProperties(Predicate p, EvaluationContext context) { return new String[] { JcrConstants.JCR_PRIMARYTYPE, JcrConstants.JCR_MIXINTYPES }; } @Override public FacetExtractor getFacetExtractor(Predicate predicate, EvaluationContext context) { return new DistinctValuesFacetExtractor(JcrConstants.JCR_PRIMARYTYPE, null, predicate.clone(), TYPE); } protected List getDescendentNodeTypes(NodeType nodeType, NodeTypeManager nodeTypeManager) throws RepositoryException { List childNodeTypes = new ArrayList(); NodeTypeIterator allTypes = nodeTypeManager.getAllNodeTypes(); while (allTypes.hasNext()) { NodeType nt = allTypes.nextNodeType(); if (Arrays.asList(nt.getSupertypes()).contains(nodeType)) { childNodeTypes.add(nt); } } return childNodeTypes; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy