AbstractOmniSearchHandler.java 15.4 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.i18n.I18n
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.ValueFactory
 *  javax.jcr.Workspace
 *  javax.jcr.observation.EventListener
 *  javax.jcr.observation.ObservationManager
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  org.apache.commons.lang.StringUtils
 *  org.apache.jackrabbit.api.observation.JackrabbitEventFilter
 *  org.apache.jackrabbit.api.observation.JackrabbitObservationManager
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.omnisearch.commons;

import com.adobe.granite.omnisearch.api.suggestion.PredicateSuggestion;
import com.adobe.granite.omnisearch.spi.core.OmniSearchHandler;
import com.day.cq.i18n.I18n;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;
import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractOmniSearchHandler
implements OmniSearchHandler,
EventListener {
    protected final String IS_SUGGESTABLE_PROPERTY = "isSuggestable";
    protected final String OMNI_SEARCH_SERVICE_USER = "omnisearch-service";
    private final String PREDICATE_GROUP_CONSTANT = "group";
    private final String PREDICATE_PROPERTY_CONSTANT = "property";
    private final String PREDICATE_VALUE_CONSTANT = "value";
    private final String PREDICATE_OR_CONSTANT = "p.or";
    public final String METADATA_PATH = "/libs/granite/omnisearch/content/metadata";
    private final String NODE_TYPE_PROPERTY = "nodeType";
    private final String OPTION_PATH_PROPERTY = "optionPaths";
    private final String PREDICATE_PATH_PROPERTY = "predicatePath";
    private final String DEFAULT_SEARCH_PATH_PROPERTY = "defaultSearchPath";
    private final String PREDICATE_TYPE_PROPERTY = "text";
    private final String INCLUDE_IN_SUGGESTIONS = "includeInSuggestions";
    private final String SUGGESTION_FROM_SEARCH_PATH_PROPERTY = "suggestionFromSearchPath";
    private final String PREDICATE_PROPERTY_NAME = "name";
    private final String LIST_ORDER = "listOrder";
    private final String LOCATION_PREDICATE = "location";
    private final String SEARCH_RAIL_PATH_PROPERTY = "searchRailPath";
    private String nodeType;
    private String _predicatePath;
    private String searchRailPath;
    private String defaultSearchPath;
    private String handlerName;
    private Boolean includeInSuggestions = false;
    private Boolean suggestionFromSearchPath = true;
    private static final Logger log = LoggerFactory.getLogger(AbstractOmniSearchHandler.class);

    @Override
    public Query getSuggestionQuery(ResourceResolver resolver, String searchTerm) {
        if (this.includeInSuggestions == null || !this.includeInSuggestions.booleanValue()) {
            return null;
        }
        try {
            String descendantNodeCondition = this.suggestionFromSearchPath != false ? " AND ISDESCENDANTNODE([" + this.getDefaultSearchPath() + "])" : "";
            String queryStr = "SELECT [rep:suggest()] FROM [" + this.getResourceType() + "] as s WHERE SUGGEST($term)" + descendantNodeCondition;
            Query query = this.createQuery(resolver, searchTerm, queryStr);
            log.debug("Suggestion query {}", (Object)query.toString());
            return query;
        }
        catch (RepositoryException e) {
            log.error("Error while creating Suggestion query", (Throwable)e);
            return null;
        }
    }

    @Override
    public List<PredicateSuggestion> getPredicateSuggestions(ResourceResolver resolver, I18n i18n, String searchTerm) {
        ArrayList<PredicateSuggestion> matchedPredicateList = new ArrayList<PredicateSuggestion>();
        List<PredicateSuggestion> predicateSuggestionList = this.getPredicateSuggestions(resolver);
        if (!predicateSuggestionList.isEmpty()) {
            for (PredicateSuggestion predicateSuggestion : predicateSuggestionList) {
                if (!i18n.getVar(predicateSuggestion.getOptionTitle()).toLowerCase().contains(searchTerm.toLowerCase())) continue;
                if (predicateSuggestion.getQueryParameters() == null) {
                    predicateSuggestion.setQueryParameters(this.getQueryParameters(predicateSuggestion, resolver));
                }
                if (resolver.getResource(predicateSuggestion.getTypePath()) == null || resolver.getResource(predicateSuggestion.getOptionPath()) == null) continue;
                matchedPredicateList.add(predicateSuggestion);
            }
        }
        return matchedPredicateList;
    }

    @Override
    public Query getSpellCheckQuery(ResourceResolver resolver, String searchTerm) {
        if (this.includeInSuggestions == null || !this.includeInSuggestions.booleanValue()) {
            return null;
        }
        try {
            String queryStr = "SELECT [rep:spellcheck()] FROM [" + this.getResourceType() + "] as s WHERE [jcr:path] = '/' AND SPELLCHECK($term)";
            Query query = this.createQuery(resolver, searchTerm, queryStr);
            log.debug("Spellcheck query {}", (Object)query.toString());
            return query;
        }
        catch (RepositoryException e) {
            log.error("Error while creating Spellcheck query", (Throwable)e);
            return null;
        }
    }

    private Query createQuery(ResourceResolver resolver, String searchTerm, String queryStr) throws RepositoryException {
        Session session = (Session)resolver.adaptTo(Session.class);
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        Query query = queryManager.createQuery(queryStr, "JCR-SQL2");
        ValueFactory vf = session.getValueFactory();
        query.bindValue("term", vf.createValue(searchTerm));
        return query;
    }

    private String getModuleConfigNodePath() {
        return "/libs/granite/omnisearch/content/metadata/" + this.getID();
    }

    @Override
    public Resource getModuleConfig(ResourceResolver resolver) {
        Resource moduleConfigResource = resolver.getResource(this.getModuleConfigNodePath());
        if (moduleConfigResource == null) {
            log.debug("no module config resource located at path {}", (Object)this.getModuleConfigNodePath());
        }
        return moduleConfigResource;
    }

    public PredicateSuggestion getLocationSuggestion(ResourceResolver resolver, I18n i18n, String searchTerm) {
        if (i18n.get(this.getName()).toLowerCase().contains(searchTerm.toLowerCase())) {
            HashMap<String, String> queryParameters = new HashMap<String, String>();
            queryParameters.put("location", this.getID());
            PredicateSuggestion locationPredicateSuggestion = new PredicateSuggestion("location", this.getName());
            locationPredicateSuggestion.setQueryParameters(queryParameters);
            return locationPredicateSuggestion;
        }
        return null;
    }

    protected String getName() {
        return this.handlerName;
    }

    protected String getResourceType() {
        return this.nodeType;
    }

    protected Resource getPredicateRootResource(ResourceResolver resolver) {
        return resolver.getResource(this.getPredicatePath());
    }

    protected String getPredicatePath() {
        return this._predicatePath;
    }

    protected String getDefaultSearchPath() {
        return this.defaultSearchPath;
    }

    private List<PredicateSuggestion> getPredicateSuggestions(ResourceResolver resolver) {
        ArrayList<PredicateSuggestion> predicateSuggestionList = new ArrayList<PredicateSuggestion>();
        String predicatePath = this.getPredicatePath();
        if (StringUtils.isNotEmpty((String)predicatePath)) {
            Resource predicateRoot = this.getPredicateRootResource(resolver);
            if (predicateRoot == null) {
                log.warn("Non-Existent Predicate Path " + predicatePath);
                return Collections.emptyList();
            }
            this.extractPredicateSuggestions(resolver, predicateSuggestionList, predicateRoot);
        } else {
            log.debug("Invalid Predicate Path {} skipping predicate suggestion loading ", (Object)predicatePath);
        }
        return predicateSuggestionList;
    }

    private void extractPredicateSuggestions(ResourceResolver resolver, List<PredicateSuggestion> predicateSuggestionList, Resource predicateRoot) {
        for (Resource predicateResource : predicateRoot.getChildren()) {
            Resource optionsRes;
            ValueMap vm = (ValueMap)predicateResource.adaptTo(ValueMap.class);
            boolean isSuggestable = (Boolean)vm.get("isSuggestable", (Object)false);
            String optionsPath = (String)vm.get("optionPaths", String.class);
            String predicateType = (String)vm.get("text", String.class);
            if (isSuggestable && optionsPath != null && predicateType != null && (optionsRes = resolver.getResource(optionsPath)) != null) {
                for (Resource resource : optionsRes.getChildren()) {
                    ValueMap optionProps = (ValueMap)resource.adaptTo(ValueMap.class);
                    String predicateTitle = (String)optionProps.get("jcr:title", String.class);
                    if (predicateTitle == null) continue;
                    PredicateSuggestion currPredicateSuggestion = new PredicateSuggestion(predicateType, predicateTitle, predicateResource.getPath(), resource.getPath());
                    currPredicateSuggestion.setQueryParameters(this.getQueryParameters(currPredicateSuggestion, resolver));
                    predicateSuggestionList.add(currPredicateSuggestion);
                }
            }
            this.extractPredicateSuggestions(resolver, predicateSuggestionList, predicateResource);
        }
    }

    protected Map<String, String> getQueryParameters(PredicateSuggestion predicateSuggestion, ResourceResolver resolver) {
        HashMap<String, String> queryParameters = new HashMap<String, String>();
        Resource predicateResource = resolver.getResource(predicateSuggestion.getTypePath());
        ValueMap vm = (ValueMap)predicateResource.adaptTo(ValueMap.class);
        String listOrder = (String)vm.get("listOrder", String.class);
        String propertyType = (String)vm.get("name", String.class);
        Resource optionResource = resolver.getResource(predicateSuggestion.getOptionPath());
        List<String> valueList = this.getOptionValuesList(optionResource);
        if (valueList.isEmpty()) {
            return null;
        }
        if (valueList.size() > 1) {
            String predicateGroupName = "group";
            if (listOrder != null) {
                predicateGroupName = listOrder + "_" + predicateGroupName;
            }
            String predicateProperty = predicateGroupName + "." + "property";
            queryParameters.put(predicateProperty, propertyType);
            int valueCount = 0;
            for (String value : valueList) {
                queryParameters.put(predicateProperty + "." + ++valueCount + "_" + "value", value);
            }
            queryParameters.put(predicateGroupName + "." + "p.or", "true");
        } else {
            String predicateProperty = "property";
            if (listOrder != null) {
                predicateProperty = listOrder + "_" + predicateProperty;
            }
            queryParameters.put(predicateProperty, propertyType);
            queryParameters.put(predicateProperty + "." + "value", valueList.get(0));
        }
        return queryParameters;
    }

    private List<String> getOptionValuesList(Resource optionResource) {
        ValueMap optionResValueMap;
        String optionvalue;
        ArrayList<String> valueList = new ArrayList<String>();
        if (optionResource != null && !"".equals(optionvalue = (String)(optionResValueMap = optionResource.getValueMap()).get("value", String.class)) && optionvalue != null) {
            valueList.add(optionvalue);
        }
        for (Resource child : optionResource.getChildren()) {
            valueList.addAll(this.getOptionValuesList(child));
        }
        return valueList;
    }

    private void updateAllProperties(ResourceResolver resolver) {
        Resource configResource = this.getModuleConfig(resolver);
        if (configResource != null) {
            Resource searchPanelResource;
            log.debug("reading configuration from {}", (Object)configResource.getPath());
            ValueMap vm = (ValueMap)configResource.adaptTo(ValueMap.class);
            this.handlerName = (String)vm.get("jcr:title", (Object)"");
            this._predicatePath = (String)vm.get("predicatePath", (Object)"");
            this.defaultSearchPath = (String)vm.get("defaultSearchPath", (Object)"");
            this.nodeType = (String)vm.get("nodeType", (Object)"");
            this.includeInSuggestions = (Boolean)vm.get("includeInSuggestions", Boolean.class);
            this.suggestionFromSearchPath = (Boolean)vm.get("suggestionFromSearchPath", (Object)true);
            this.searchRailPath = (String)vm.get("searchRailPath", (Object)"");
            if (!StringUtils.isEmpty((String)this.searchRailPath) && (searchPanelResource = resolver.getResource(this.searchRailPath)) != null) {
                ValueMap searchProperties = (ValueMap)searchPanelResource.adaptTo(ValueMap.class);
                this._predicatePath = (String)searchProperties.get("predicatePath", (Object)"");
            }
            this.invalidated();
        }
    }

    private void invalidated() {
    }

    public void init(ResourceResolver resolver) {
        Session session = (Session)resolver.adaptTo(Session.class);
        try {
            String moduleConfigPath = this.getModuleConfigNodePath();
            log.debug("calling init for {}", (Object)moduleConfigPath);
            JackrabbitEventFilter eventFilter = new JackrabbitEventFilter().setAbsPath(moduleConfigPath).setEventTypes(31).setIsDeep(true).setNoLocal(true);
            JackrabbitObservationManager observationManager = (JackrabbitObservationManager)session.getWorkspace().getObservationManager();
            this.updateAllProperties(resolver);
            observationManager.addEventListener((EventListener)this, eventFilter);
        }
        catch (RepositoryException e) {
            log.error("Error while initializing ", (Throwable)e);
        }
    }

    public void destroy(ResourceResolver resolver) {
        this.invalidated();
        Session session = (Session)resolver.adaptTo(Session.class);
        try {
            if (session != null) {
                session.getWorkspace().getObservationManager().removeEventListener((EventListener)this);
            }
            resolver.close();
        }
        catch (RepositoryException re) {
            log.error("Error while deactivating the OmniSearchHandler", (Throwable)re);
        }
    }
}