Skip to content

Paginated Search Service to Execute Actions

Loop through a result set, and execute an action on the objects.
This example uses

  • Alfresco Webscript
  • Alfresco Actions Service
  • Alfresco Search Service

The Webscript to execute this logic looks like the following:

/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
*/
package com.swazzy.platformsample;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;


public class PaginatedSearch extends DeclarativeWebScript {
    private static Log logger = LogFactory.getLog(PaginatedSearch.class);
    private static final String PAGE_SIZE = "pageSize";
    public static final String ACTION_NAME = "action";
    public static final String CMIS_QUERY = "cmisQuery";
    public static final String ACTION_PROPS = "actionProps";
    public static final String EXEC_ASYNC = "async";
    private SearchService searchService;
    private ActionService actionService;

    protected Map<String, Object> executeImpl(
            WebScriptRequest req, Status status, Cache cache) {
        Map<String, Object> model = new HashMap<String, Object>();

        final int maxSize = Integer.parseInt(req.getParameter(PAGE_SIZE));
        final String actionName = req.getParameter(ACTION_NAME);
        final String cmisQuery = req.getParameter(CMIS_QUERY);
        final String actionProps = req.getParameter(ACTION_PROPS);
        final Boolean async = Boolean.parseBoolean(req.getParameter(EXEC_ASYNC));
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Serializable> map = new HashMap<>();
        try {
            map = mapper.readValue(actionProps, new TypeReference<Map<String, Serializable>>() {
            });
        } catch (IOException ioe) {
            logger.error("Can't read values", ioe);
        }
        int endIndex = maxSize;
        int skipCount = 0;
        final Map<String,Serializable> fMap = map;
        Boolean hasMore;
        int count=0;
        do {
            SearchParameters parameters = SearchParametersBuilder.aSearchParameters()
                    .withLanguage(SearchService.LANGUAGE_CMIS_ALFRESCO)
                    .withLimit(endIndex)
                    .withLimitBy(LimitBy.FINAL_SIZE)
                    .withMaxItems(endIndex)
                    .withMaxPermissionChecks(endIndex)
                    .withSkipCount(skipCount)
                    .withQuery(cmisQuery)
                    .withStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)
                    .build();

            ResultSet set = searchService.query(parameters);
            hasMore = set.hasMore();


            if (set != null) {
                set.getNodeRefs().forEach(nodeRef -> {
                    Action action = actionService.createAction(actionName);
                    action.setParameterValues(fMap);
                    actionService.executeAction(action, nodeRef,false,async);
                });
                set.close();
            }
            skipCount = endIndex;
            endIndex += maxSize;
            count++;
        } while (hasMore);
        model.put("total", count);

        return model;
    }

    public void setActionService(ActionService actionService) {
        this.actionService = actionService;
    }

    public void setSearchService(SearchService searchService) {
        this.searchService = searchService;
    }
}

SearchBuilder Wrapper

package com.swazzy.platformsample;

import org.alfresco.repo.search.MLAnalysisMode;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.*;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.namespace.NamespaceService;

import java.util.ArrayList;


public final class SearchParametersBuilder {
    /*
     * The parameters that can be set
     */
    private String language;
    private String query;
    private MLAnalysisMode mlAnalaysisMode = null; // Pick up from config if null
    private LimitBy limitBy = LimitBy.UNLIMITED;
    private PermissionEvaluationMode permissionEvaluation = PermissionEvaluationMode.EAGER;
    private int limit ;
    private int maxItems = -1;
    private int skipCount = 0;
    private SearchParameters.Operator defaultFTSOperator = SearchParameters.Operator.OR;
    private String namespace = NamespaceService.CONTENT_MODEL_1_0_URI;
    // By default uses the central config
    private int maxPermissionChecks = -1;
    private ArrayList stores = new ArrayList(1);
    // By default uses the central config
    private long maxPermissionCheckTimeMillis = -1;
    private String defaultFieldName = "TEXT";
    private Boolean useInMemorySort;
    private Integer maxRawResultSetSizeForInMemorySort;
    private boolean excludeTenantFilter = false;
    private QueryConsistency queryConsistency = QueryConsistency.DEFAULT;
    private Long sinceTxId;
    private String searchTerm;
    private boolean spellCheck;

    private GeneralHighlightParameters highlight;

    private SearchParametersBuilder() {
    }

    public static SearchParametersBuilder aSearchParameters() {
        return new SearchParametersBuilder();
    }

    public SearchParametersBuilder withLanguage(String language) {
        this.language = language;
        return this;
    }

    public SearchParametersBuilder withQuery(String query) {
        this.query = query;
        return this;
    }

    public SearchParametersBuilder withMlAnalaysisMode(MLAnalysisMode mlAnalaysisMode) {
        this.mlAnalaysisMode = mlAnalaysisMode;
        return this;
    }

    public SearchParametersBuilder withLimitBy(LimitBy limitBy) {
        this.limitBy = limitBy;
        return this;
    }

    public SearchParametersBuilder withStore(StoreRef store) {
        this.stores.add(store);
        return this;
    }
    public SearchParametersBuilder withPermissionEvaluation(PermissionEvaluationMode permissionEvaluation) {
        this.permissionEvaluation = permissionEvaluation;
        return this;
    }

    public SearchParametersBuilder withLimit(int limit) {
        this.limit = limit;
        return this;
    }

    public SearchParametersBuilder withMaxItems(int maxItems) {
        this.maxItems = maxItems;
        return this;
    }

    public SearchParametersBuilder withSkipCount(int skipCount) {
        this.skipCount = skipCount;
        return this;
    }

    public SearchParametersBuilder withDefaultFTSOperator(SearchParameters.Operator defaultFTSOperator) {
        this.defaultFTSOperator = defaultFTSOperator;
        return this;
    }

    public SearchParametersBuilder withNamespace(String namespace) {
        this.namespace = namespace;
        return this;
    }

    public SearchParametersBuilder withMaxPermissionChecks(int maxPermissionChecks) {
        this.maxPermissionChecks = maxPermissionChecks;
        return this;
    }

    public SearchParametersBuilder withMaxPermissionCheckTimeMillis(long maxPermissionCheckTimeMillis) {
        this.maxPermissionCheckTimeMillis = maxPermissionCheckTimeMillis;
        return this;
    }

    public SearchParametersBuilder withDefaultFieldName(String defaultFieldName) {
        this.defaultFieldName = defaultFieldName;
        return this;
    }

    public SearchParametersBuilder withUseInMemorySort(Boolean useInMemorySort) {
        this.useInMemorySort = useInMemorySort;
        return this;
    }

    public SearchParametersBuilder withMaxRawResultSetSizeForInMemorySort(Integer maxRawResultSetSizeForInMemorySort) {
        this.maxRawResultSetSizeForInMemorySort = maxRawResultSetSizeForInMemorySort;
        return this;
    }

    public SearchParametersBuilder withExcludeTenantFilter(boolean excludeTenantFilter) {
        this.excludeTenantFilter = excludeTenantFilter;
        return this;
    }

    public SearchParametersBuilder withQueryConsistency(QueryConsistency queryConsistency) {
        this.queryConsistency = queryConsistency;
        return this;
    }

    public SearchParametersBuilder withSinceTxId(Long sinceTxId) {
        this.sinceTxId = sinceTxId;
        return this;
    }

    public SearchParametersBuilder withSearchTerm(String searchTerm) {
        this.searchTerm = searchTerm;
        return this;
    }

    public SearchParametersBuilder withSpellCheck(boolean spellCheck) {
        this.spellCheck = spellCheck;
        return this;
    }

    public SearchParametersBuilder withHighlight(GeneralHighlightParameters highlight) {
        this.highlight = highlight;
        return this;
    }

    public SearchParameters build() {
        final SearchParameters searchParameters = new SearchParameters();
        searchParameters.setLanguage(language);
        searchParameters.setQuery(query);
        searchParameters.setMlAnalaysisMode(mlAnalaysisMode);
        searchParameters.setLimitBy(limitBy);
        searchParameters.setPermissionEvaluation(permissionEvaluation);
        searchParameters.setLimit(limit);
        searchParameters.setMaxItems(maxItems);
        searchParameters.setSkipCount(skipCount);
        searchParameters.setDefaultFTSOperator(defaultFTSOperator);
        searchParameters.setNamespace(namespace);
        searchParameters.setMaxPermissionChecks(maxPermissionChecks);
        searchParameters.setMaxPermissionCheckTimeMillis(maxPermissionCheckTimeMillis);
        searchParameters.setDefaultFieldName(defaultFieldName);
        searchParameters.setUseInMemorySort(useInMemorySort);
        searchParameters.setMaxRawResultSetSizeForInMemorySort(maxRawResultSetSizeForInMemorySort);
        searchParameters.setExcludeTenantFilter(excludeTenantFilter);
        searchParameters.setQueryConsistency(queryConsistency);
        searchParameters.setSinceTxId(sinceTxId);
        searchParameters.setSearchTerm(searchTerm);
        searchParameters.setSpellCheck(spellCheck);
        searchParameters.setHighlight(highlight);
        stores.forEach(store -> searchParameters.addStore(store));
        return searchParameters;
    }
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: